I have code that generates a concatenated (r-s) signature for the ECDSA signature using jsrsasign
and a key in JWK format:
const sig = new Signature({ alg: 'SHA256withECDSA' });
sig.init(KEYUTIL.getKey(key));
sig.updateHex(dataBuffer.toString('hex'));
const asn1hexSig = sig.sign();
const concatSig = ECDSA.asn1SigToConcatSig(asn1hexSig);
return new Buffer(concatSig, 'hex');
Seems to work. I also have code that uses SubtleCrypto
to achieve the same thing:
importEcdsaKey(key, 'sign') // importKey JWK -> raw
.then((privateKey) => subtle.sign(
{ name: 'ECDSA', hash: {name: 'SHA-256'} },
privateKey,
dataBuffer
))
These both return 128-byte buffers; and they cross-verify (i.e. I can verify jsrsasign
signatures with SubtleCrypto
and vice versa). However, when I use the Sign
class in the Node.js crypto
module, I seem to get something quite different.
key = require('jwk-to-pem')(key, {'private': true});
const sign = require('crypto').createSign('sha256');
sign.update(dataBuffer);
return sign.sign(key);
Here I get a buffer of variable length, roughly 70 bytes; it does not cross-verify with jsrsa
(which bails complaining about an invalid length for an r-s signature).
How can I get an r-s signature, as generated by jsrsasign
and SubtleCrypto
, using Node crypto
?
require('jwk-to-pem')(key, {'private': true});
produces a valid encoding of an EC private key that the crypto module understands? Does it begin with----- BEGIN EC PRIVATE KEY ------
as in the example? – HeadfirstEC PRIVATE KEY
section, and thecrypto
module doesn’t issue any kind of errors or warnings, it just issues a signature different from what I expected. – Wineglass