2015-05-13 70 views
2

我想在node.js文件上执行RSA-SHA512。我可以计算与openssl相匹配的给定数据文件的sha512哈希值。 但是,当试图在同一个散列上获取数字签名时,node.js签名与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

“*我首先计算整个文件的sha256哈希,并将此哈希作为输入传递给签名函数*” - 我没有在您提供的代码中使用哈希函数。这不是你真正的代码,还是我误解你的描述? – apsillers

+0

其实我有我的数据文件散列存储在/ tmp/data,这是我在阅读上面的代码签名。 对不起,不适用的文件命名。 –

回答

3

当您向签名程序提供输入时,它可能会假定输入尚未散列,并且在签名前将其散列。这里的问题是节点(重新)散列输入,而rsautl正在使用输入。 (请注意,即使你单独将其提供给rsautl前重新散列输入,它仍然无法匹配,因为rsautl不使用ASN1编码;见下文)

为了使OpenSSL的产生SHA256哈希制造前RSA签名(如Node一样),你需要使用dgst命令与-sha256-sign参数:

openssl dgst -sha256 -sign /tmp/boot2-prvKey.pem -hex < /tmp/data 

这将哈希/tmp/data并签署与RSA的哈希,这是节点的RSA-SHA256签名者究竟是干什么的。

有关更多信息,请参见Difference between openSSL rsautl and dgst

简单的答案是,dgst -sign创建一个哈希,ASN1编码,然后签署ASN1编码的哈希值,而rsautl -sign刚刚签署输入而不散列或ASN1编码。

节点的sign方法的行为就像是dgst -sign而非rsautl -sign

节点似乎没有提供类似于内置rsautl的签名机制,而不使用散列和ASN1编码。出于这个原因,您可能需要直接签署文档,而不是使用文档的散列。如果您出于某种原因确实无法完成此任务,则可以下载Node rsautl module from NPM,它为rsautl提供节点绑定。

+0

但是从评论中看到这一点:*“...实际上我有我的数据文件散列存储在/tmp/data..."*。所以看起来他已经有了哈希。我认为他需要将签名函数应用于哈希。或者他需要允许OpenSSL命令完成这一切(如上面所示)。如果他正在签名,那么签署*未知*哈希或*未知*文件可能是危险的。我认为这同样适用于验证,但不像签署散列那样糟糕。它应该是对文档的原子操作,而不是分立部分的离散操作。 – jww

0

问题是您的Openssl命令只是签署了您的数据而没有散列函数。 必须首先散列与OpenSSL和具有相同的功能,在你的NodeJS代码的数据(SHA-256)再签收哈希在命令中获得最终签名: openssl rsautl -sign -in /tmp/data -inkey /tmp/boot2-prvKey.pem -out sig

你可以看到,在这个命令你没有指定任何散列函数。

要获得签名:数据 - > SHA-256散列= - > RSA签名=

我还没有足够的时间来测试它,给你正确的代码,我希望这将是有益的。

+0

嗨保罗,感谢您的回复。 我确实计算了我的数据文件的哈希值。哈希存储在/ tmp/data中。 用openssl和node.js计算的哈希(sha256)完全匹配,因此我跳过代码中的那部分,而只有给定哈希上的符号不同。因此,我明确表示两种情况都只有签署部分。 –