php 和 node.js 之间 pbkdf2 的差异
Differences in pbkdf2 between php and node.js
我正在使用 Node.js 使用 pbkdf2 生成密码散列并将它们存储到数据库中。此外,我正在制作一些使用 php 制作的网页,让您的用户重置他们的密码,因此除非我在 node.js 中使用网络服务来构建哈希,否则我希望算法在2个系统。不幸的是,我得到的结果似乎不同,而且我无法混合使用这两个库。我在 node.js 中使用的代码使用基本上调用 crypto.pbkdf2 的模块 password-hash-and-salt,而 php 使用 hash_pbkdf2.
这些是我用来测试它的脚本:
PHP:
<?php
$password = $argv[1];
$iterations = 10000;
$length = 64;
$salt = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
$key = hash_pbkdf2("sha256", $password, $salt, $iterations, $length,true);
echo "HASH: pbkdf2\$" . $iterations . "\$" . bin2hex($key) . "\$" . bin2hex($salt). "\n";
echo "Key length: " . strlen(bin2hex($key)) . "\n";
echo "Hash length: " . strlen(bin2hex($salt)) . "\n";
?>
NODE.JS:
var crypto = require('crypto');
var request = require('request');
var hasher = require('password-hash-and-salt');
if (process.argv[2] == 'generate') {
var password = process.argv[3];
console.log("Generating hash for password " + password);
hasher(password).hash(function(err, hash) {
if (err) {
console.log(err);
} else {
console.log("Result: " + hash);
}
});
} else {
var password = process.argv[3];
var hash = process.argv[4];
console.log("Testing " + password + " against " + hash);
hasher(password).verifyAgainst(hash, function(error, verified) {
if (error) console.log(error);
else {
console.log("Verification result: " + verified);
}
});
}
NODE.JS 库部分:
var calcHash = function() {
crypto.pbkdf2(password, salt, iterations, 64, function(err, key) {
if(err)
return callback(err);
var res = 'pbkdf2$' + iterations +
'$' + key.toString('hex') +
'$' + salt.toString('hex');
callback(null, res);
})
};
if(!salt) {
crypto.randomBytes(64, function(err, gensalt) {
if(err)
return callback(err);
salt = gensalt;
calcHash();
});
} else {
calcHash();
}
谁能告诉我哪里做错了或者算法不兼容?
谢谢!
NodeJS PBKDF2 默认为 SHA-1,这应该可以解释差异。
强烈建议您直接使用 NodeJS PBKDF2 函数。您的 JS 包装器(您不 link 使用它)也使用它,它只不过是一个小的包装器库。
我正在使用 Node.js 使用 pbkdf2 生成密码散列并将它们存储到数据库中。此外,我正在制作一些使用 php 制作的网页,让您的用户重置他们的密码,因此除非我在 node.js 中使用网络服务来构建哈希,否则我希望算法在2个系统。不幸的是,我得到的结果似乎不同,而且我无法混合使用这两个库。我在 node.js 中使用的代码使用基本上调用 crypto.pbkdf2 的模块 password-hash-and-salt,而 php 使用 hash_pbkdf2.
这些是我用来测试它的脚本:
PHP:
<?php
$password = $argv[1];
$iterations = 10000;
$length = 64;
$salt = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
$key = hash_pbkdf2("sha256", $password, $salt, $iterations, $length,true);
echo "HASH: pbkdf2\$" . $iterations . "\$" . bin2hex($key) . "\$" . bin2hex($salt). "\n";
echo "Key length: " . strlen(bin2hex($key)) . "\n";
echo "Hash length: " . strlen(bin2hex($salt)) . "\n";
?>
NODE.JS:
var crypto = require('crypto');
var request = require('request');
var hasher = require('password-hash-and-salt');
if (process.argv[2] == 'generate') {
var password = process.argv[3];
console.log("Generating hash for password " + password);
hasher(password).hash(function(err, hash) {
if (err) {
console.log(err);
} else {
console.log("Result: " + hash);
}
});
} else {
var password = process.argv[3];
var hash = process.argv[4];
console.log("Testing " + password + " against " + hash);
hasher(password).verifyAgainst(hash, function(error, verified) {
if (error) console.log(error);
else {
console.log("Verification result: " + verified);
}
});
}
NODE.JS 库部分:
var calcHash = function() {
crypto.pbkdf2(password, salt, iterations, 64, function(err, key) {
if(err)
return callback(err);
var res = 'pbkdf2$' + iterations +
'$' + key.toString('hex') +
'$' + salt.toString('hex');
callback(null, res);
})
};
if(!salt) {
crypto.randomBytes(64, function(err, gensalt) {
if(err)
return callback(err);
salt = gensalt;
calcHash();
});
} else {
calcHash();
}
谁能告诉我哪里做错了或者算法不兼容?
谢谢!
NodeJS PBKDF2 默认为 SHA-1,这应该可以解释差异。
强烈建议您直接使用 NodeJS PBKDF2 函数。您的 JS 包装器(您不 link 使用它)也使用它,它只不过是一个小的包装器库。