Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 741
iandotkelly Avatar asked Jun 29 '12 01:06

iandotkelly


1 Answers

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');
like image 129
iandotkelly Avatar answered Sep 25 '22 10:09

iandotkelly