我想对 node.js 中的文件执行 RSA-SHA512。我可以计算给定数据文件的 sha512 哈希值,该哈希值与 openssl 的哈希值相匹配。 然而,当尝试在同一哈希上获取数字签名时,node.js 签名与 openssl 签名不同。 下面是一个示例代码片段:
var data = new Buffer(512);
data = fs.readFileSync('/tmp/data');
var pem = fs.readFileSync('/tmp/boot2-prvKey.pem');
var privateKey = pem.toString('ascii');
var signer = crypto.createSign("RSA-SHA256");
signer.update(data);
var sign = signer.sign(privateKey, 'hex');
console.log("SIGN " + sign + '\n');
用于签署数据的 Openssl 命令:
openssl rsautl -sign -in /tmp/data -inkey /tmp/boot2-prvKey.pem -out sig
以上两者都会生成不同的签名。
我有几个问题 1)我想计算一个文件的RSA-SHA256,所以我首先计算整个文件的sha256哈希,并将该哈希作为签名函数的输入传递。 这是正确的做法吗? 2)如果是,上面的代码可能出了什么问题?如果不是,正确的方法是什么?
我使用的node.js版本是0.10.36,openssl版本是1.0,1。
最佳答案
当您向签名程序提供输入时,它可能会假设该输入尚未经过哈希处理,并会在签名之前对其进行哈希处理。这里的问题是 Node 正在对输入进行(重新)哈希处理,而 rsautl 则按原样使用输入。 (请注意,即使您在将输入提供给 rsautl
之前单独重新哈希输入,它仍然不匹配,因为 rsautl
不使用 ASN1 编码;请参见下文。)
要使 OpenSSL 在生成 RSA 签名之前生成 SHA256 哈希(如 Node 那样),您需要将 dgst
命令与 -sha256
和 一起使用-sign
参数:
openssl dgst -sha256 -sign /tmp/boot2-prvKey.pem -hex < /tmp/data
这将散列 /tmp/data
并使用 RSA 对散列进行签名,这正是 Node 的 RSA-SHA256
签名者所做的事情。
参见Difference between openSSL rsautl and dgst欲了解更多信息:
The simple answer is that
dgst -sign
creates a hash, ASN1 encodes it, and then signs the ASN1 encoded hash, whereasrsautl -sign
just signs the input without hashing or ASN1 encoding.
Node 的 sign
方法的行为类似于 dgst -sign
而不是 rsautl -sign
。
Node 似乎没有提供类似 rsautl 的内置机制,无需散列和 ASN1 编码即可进行签名。因此,您可能需要直接对文档进行签名,而不是对文档的哈希进行操作。如果由于某种原因您确实无法做到这一点,您可以下载Node rsautl
module from NPM ,它为 rsautl
提供 Node 绑定(bind)。
关于node.js 加密签名和 openssl 签名不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30213659/