nodejs crypto和c++ openssl 的RSA签名结果不一致?
发布于 8 年前 作者 leewill1120 5365 次浏览 来自 问答

nodejs:

const crypto = require(‘crypto’) const fs = require(‘fs’) var privateKey = fs.readFileSync(‘private.pem’).toString(‘utf8’) const sign = crypto.createSign(‘RSA-SHA256’); // RSA-SHA256和SHA256结果一样 sign.update(“test”, ‘acsii’) var signature = sign.sign(privateKey, ‘hex’) console.log(signature) output: 279d0ec2405e29db7024217dd19bc939b0d149a69335f52943ec42f0b40668a38b6d7d0661b71552d61bf6a541680e4e542fa18e0bcbb860a7f57ec0fb89c3ea8e5cdce2bf6b8c71f0c1462a9cf228e9eb85b00360201ac0c512a1d701c4bacf2bfc6a256e2e6451a88fb0aad849cf44e0fb947c5e315c5289ef09eebee5e05d

c++:

int main(int argc, char **argv){ ERR_load_ERR_strings(); ERR_load_RSA_strings(); ERR_load_PEM_strings(); ERR_load_BIO_strings();

string strPemFileName="private.pem";
FILE* hPriKeyFile = fopen(strPemFileName.c_str(), "rb");
if( hPriKeyFile == NULL )
{
    assert(false);
    return 1;
}
RSA* pRSAPriKey = RSA_new();
if(PEM_read_RSAPrivateKey(hPriKeyFile, &pRSAPriKey, 0, 0) == NULL)
{
    assert(false);
    return 1;
}
unsigned int sig_len = 0;
unsigned int len = 1024;
char * out = (char *)malloc(len);
memset(out, 0, len);
string context="test";
unsigned char md[SHA256_DIGEST_LENGTH] = {0};
if(1 != RSA_sign(NID_sha256,(unsigned char*)context.c_str(), context.size(), (unsigned char*)out, &sig_len,pRSAPriKey))
{
    char szErrMsg[LEN_1024] = { 0 };
    ERR_error_string_n(ERR_get_error(), szErrMsg, LEN_1024);
    cout << szErrMsg << endl;
}
print_hex((unsigned char *)out, sig_len);
free(out);
return 0;

} output: 3446ed9d60bde475f6f2844c5c98fcedf08578617243ab378231db574b1685f2f82ce50da36263dccf6ec9152160dc66c5e0d3a7cfc5de311300cecb29c1b0135b876e024ef13a50d345c4d37bcf53e147a235e72cc0a40d160e37eb1abbf4e18deb132e68f5155b324b7ad95daa38c44dd607e0b1d7d1c1370d6cceebe7ad1e

9 回复

这里为什么用 “utf8”:

var privateKey = fs.readFileSync(‘private.pem’).toString(‘utf8’)

而下面这里又用 “hex”:

var signature = sign.sign(privateKey, ‘hex’)

@zbinlin 这两个没有什么关系,第一个是指定key文件中的编码,因为key中都是普通字符没有中文,所以utf8和ascii都是一样的,第二个hex是让生成的签名以16进制字符串输出

@leewill1120 嗯,我记错参数了,确实没什么关系。

有用 openssl 命令行试过吗?我试下了,发现 node.js 里的结果跟 openssl 命令行的一致。

@zbinlin 命令行你是用怎样的参数呢

@leewill1120 echo -n 'test' | openssl dgst -sha256 -sign private.pem -hex

@zbinlin 是c++程序的问题,c++中要先用sha256计算摘要,然后对摘要进行签名,而在nodejs中这两步合在一起做了。多谢。

建议不要用 crypto, 用ursa 来做,这些坑我都踩过了。。。。。node 的crypto 不适合做异构对接的。。。

@cnlile 都有哪些坑呢,最好能整理出一篇文章,这方面的资料太少了

回到顶部