我想在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。
答案 0 :(得分:4)
当您为签名程序提供输入时,它可能会假设输入尚未进行哈希处理,并在签名之前对其进行哈希处理。这里的问题是Node(重新)散列输入,而null
正在使用输入。 (请注意,即使您在将输入提供给<?php
class Aaa
{
protected $var = null;
public function powerOnYou()
{
var_dump($this->var);
}
}
class Bbb extends Aaa
{
public function performSomething()
{
$this->var = 'Now we have a string, not more null value';
$this->powerOnYou();
}
}
$bbb = New Bbb();
$bbb->performSomething();
之前单独重新哈希输入,它仍然不匹配,因为rsautl
不使用ASN1编码;请参阅下文。)
要使OpenSSL在进行RSA签名之前生成SHA256哈希(如Node所做的那样),您需要使用带有rsautl
和rsautl
参数的dgst
命令:
-sha256
这将散列-sign
并使用RSA签署散列,这正是Node的openssl dgst -sha256 -sign /tmp/boot2-prvKey.pem -hex < /tmp/data
签名者所做的。
有关详细信息,请参阅Difference between openSSL rsautl and dgst:
简单的答案是
/tmp/data
创建一个哈希,ASN1对其进行编码,然后对ASN1编码的哈希进行签名,而RSA-SHA256
只是在没有哈希或ASN1编码的情况下对输入进行签名。
Node的dgst -sign
方法的行为类似于rsautl -sign
,而不是sign
。
节点似乎没有提供内置的dgst -sign
- 类似于没有散列和ASN1编码的签名机制。因此,您可能需要直接签署文档,而不是对文档的哈希进行操作。如果由于某种原因你真的不能这样做,你可以下载Node rsautl
module from NPM,它为rsautl -sign
提供节点绑定。
答案 1 :(得分:0)
问题是你的Openssl命令只是在没有哈希函数的情况下签署你的数据。
您必须首先使用openssl散列数据并使用与nodejs代码(SHA-256)中相同的函数,然后使用您的命令对散列进行签名以获取最终签名:
openssl rsautl -sign -in /tmp/data -inkey /tmp/boot2-prvKey.pem -out sig
你可以看到在这个命令中你没有指定任何哈希函数。
获取签名:数据 - &gt; SHA-256 =哈希 - &gt; RSA =签名
我没有足够的时间来测试它并给你正确的代码,我希望它会有所帮助。