at first,we use elliptic crypto package . the sign function looks like this:
signByPriv = function (privKeyData, text) {
let msgHash = getmsgHash(text, "SHA-384");
let key = ec.keyFromPrivate(Buffer.from(privKeyData,'base64').toString('hex'), 'hex')
let signature = key.sign(msgHash);
return signature
}
then we wanna change it to nodejs version,cause nodejs use openssl under the hood。so it will be faster
at first my sign function as below:
signByPriv = function (privKeyData, text) {
const sign1 = crypto.createSign('SHA384'); //hash do inside
sign1.write(text);
sign1.end();
const signature = sign1.sign(privKeyData, 'hex');
return signature;
}
it will complain about the error:
internal/crypto/sig.js:86 const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding,
Error: error:0909006C:PEM routines:get_name:no start line
so I checked the nodejs docs,and found it need to pass the privKey with pem format。
signByPriv = function (privKeyData, text) {
let key = turnBase64PrivToPemKey(privKeyData) //base64 => pem
const sign1 = crypto.createSign('SHA384'); //hash do inside
sign1.write(text);
sign1.end();
const signature = sign1.sign(privKeyData, 'hex');
return signature;
}
turnBase64PrivToPemKey = function (base64Priv) {
var key_hex = Buffer.from(base64Priv, 'base64').toString('hex');
ecdh.setPrivateKey(key_hex, 'hex')
var pubKey_hex = ecdh.getPublicKey().toString('hex');
//pem格式私钥文件是由固定字符加上私钥和公钥拼接而成==同一条曲线,固定字符相同
var mykey = '308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420' + key_hex + 'a144034200' + pubKey_hex;
privKey = '-----BEGIN PRIVATE KEY-----\n' + Buffer.from(mykey, 'hex').toString('base64') + '\n-----END PRIVATE KEY-----';
pubKey = crypto.createPublicKey(privKey); //也可恢复出公钥
let Key = {
privKey,
pubKey
}
return Key;
}
and great,the sign and verify functions all works perfect。
but the backend may do the same stupid thing...
the curve we chose is prime256v1
const ecdh = crypto.createECDH('prime256v1')
so,I wonder why nodejs sign func can't accept only a base64 priv?
cause the pem format is only composed by private key,public key and other fixed string.