Node.js verify function does not verify signature when openssl command line does
I am trying to use the Node.js crypto module to verify a signature for some data. I am using Node.js 0.8.0.
The data in a file has been hashed using the MD5 algorithm and signed using a private RSA key, and the signature saved to a separate file. This has all been done using Java libraries.
If I use openssl to verify the signature this is successful, using:
openssl dgst -verify mykey.pem -signature example.sig hello.txt
It responds with
Verified OK. If I change a single character of hello.txt it does not verify. I can add a -MD5 parameter to the above command and it still works, but I presume this is the default, but if I say -MD4 or -SHA it does not verify. This is all good.
If I then try to use the Node crypto module, which wraps openssl, I cannot get this verification to work.
My example code is:
var crypto = require("crypto"); var fs = require("fs"); var data = fs.readFileSync("./hello.txt"); var pubkey = fs.readFileSync("./mykey.pem", "utf8"); var signature = fs.readFileSync("./example.sig"); var verifier = crypto.createVerify ('RSA-MD5'); verifier.update (data); var success = verifier.verify (pubkey, signature); console.log(success);
This allways outputs
false. I have tried:
- reading the data as 'utf8' and 'ascii' encoded, as it is a text file.
- reading the key as 'ascii' encoded (I have reason to think the key is fine as I was getting some exceptions when I was loading an incorrectly encoded key at one point)
- using MD5 instead of RSA-MD5 as the digest algorithm
- loading a base64 encoded signature rather than binary, and putting the 'base64' parameter on the verify function.
Am I misinterpreting that my code is performing the same operation as the openssl command line I show here? Any suggestions for how to resolve this?
Update: I have also tried using a self-signed trusted certificate rather than just a key. I have confirmed that openssl verifies the certificate, and yet the node crypto library does not verify the file.
I finally found that it was a signature format problem - verify has a third parameter, which defaults to 'binary' when I had the 'hex' format.
The final solution moved to using the SHA1 hash and now runs on node 0.10 which has a slightly different stream API, but the relevant line that has changed is:
result = verifier.verify(publicKey, signature, 'hex');