2015-09-29 57 views
4

我正在PBKDF2前端(CryptoJS)和後端(Node.js), 兩個派生的密鑰必須相等,所以我使用相同的鹽,相同的算法,迭代次數相同,密碼相同,但派生密鑰不同。Nodejs crypto.pbkdf2結果不同於CryptoJS.PBKDF2

這是瀏覽器/ cryptoJS代碼,在註釋示例鹽和密鑰。 (十六進制)

<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」開頭。

錯誤在哪裏?也許這是一個不同的庫實現?不應該是相同的派生密鑰?

回答

7

當你

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

你得到隨機字節,而是一個字節。當您在salt.js中將鹽編碼爲UTF-8字符串時,您將使用與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, 
+0

哦!明白了,我正在將salt轉換爲utf8,因爲crypto.pbkdf2希望鹽作爲字符串,但我完全忘記了生成爲Byte:D 非常感謝! – TheZero