Nodejs crypto.pbkdf2结果不同于CryptoJS.PBKDF2

我在前端(CryptoJS)和后端(Node.js)上使用PBKDF2,两个派生密钥必须相同,所以我使用相同的salt,相同的algorithm,相同的迭代次数,相同的密码,但派生的密钥是不同。

这是浏览器/ cryptoJS代码,在注释示例盐和密钥。 (hex)

<script type="text/javascript" src="pbkdf2.js"></script> <script type="text/javascript" src="sha512.js"></script> <script> var salt = CryptoJS.lib.WordArray.random(128 / 8); var key512Bits = CryptoJS.PBKDF2('anacleto', salt, { hasher:CryptoJS.algo.SHA512, keySize: 512 / 32, iterations: 1 }); console.log(salt.toString(CryptoJS.enc.Hex)); // 1427f23fd32f8f9902768e7ab7c7ffad console.log(key512Bits.toString(CryptoJS.enc.Hex)); // de3259de39fcc55531b91b4ffb2a6c29005c674cc95b3ec5bdf18412b6087d05921f3a0e4148fc34c88a04e980481d397a4c2b143edc0cb1bb5d7434ca3b4c25 </script> 

这是nodeJS代码

 var crypto = require('crypto'); var salt_hex = '1427f23fd32f8f9902768e7ab7c7ffad'; var key_hex = 'de3259de39fcc55531b91b4ffb2a6c29005c674cc95b3ec5bdf18412b6087d05921f3a0e4148fc34c88a04e980481d397a4c2b143edc0cb1bb5d7434ca3b4c25'; var salt = new Buffer(salt_hex, 'hex'); crypto.pbkdf2('anacleto', salt.toString('utf8'), 1, 512/8, 'sha512', function (err, key) { if (err) throw err; var x = key.toString('hex'); var y = key_hex; console.assert(x === y, '\n' + x + '\n !== \n' + y); }); 

而控制台出现这个断言错误:

 AssertionError: efcca398dc0eb07aec6dcf2239dae83b79c2f82212b2cc0a21270fe251c73c7ab69f0133e75bf3ca6159242826ff3f26c64075f72cf86c67ba1199af29f6d576 !== de3259de39fcc55531b91b4ffb2a6c29005c674cc95b3ec5bdf18412b6087d05921f3a0e4148fc34c88a04e980481d397a4c2b143edc0cb1bb5d7434ca3b4c25 

正如你所看到的,node.js的密钥以“efcca”开始,而CryptoJS以“de325”开头。

错误在哪里? 也许这是一个不同的库实现? 不应该是相同的派生关键?

当你这样做

 var salt = CryptoJS.lib.WordArray.random(128 / 8); 

你得到随机字节,但字节。 当你在salt.js中将salt编码为一个UTF-8string时,你将使用与node.js不同的编码方式。

更改

 crypto.pbkdf2('anacleto', salt.toString('utf8'), 1, 512/8, 

 crypto.pbkdf2('anacleto', salt, 1, 512/8, 

要么

 crypto.pbkdf2('anacleto', salt.toString('binary'), 1, 512/8,