NodeJS:加密 - 无论输入什么,我为什么得到相同的散列?
我正在使用加密哈希字符串与盐200次。我有一个奇怪的行为,散列总是相同的。我现在已经返回看起来是正确的结果,但我想知道是否有人可以告诉我为什么。NodeJS:加密 - 无论输入什么,我为什么得到相同的散列?
这是每一个时间(假定相同的盐),得到相同的哈希的原代码:
const crypto = require('crypto');
console.log(hashPwd('abc', '11111111111111111111111111111111'));
console.log(hashPwd('def', '11111111111111111111111111111111'));
function hashPwd(password, hexSalt){
var salt = hex2a(hexSalt);
var hashPwd = crypto.createHash('sha256').update(salt + password);
for(var x =0; x < 199; x++){
hashPwd = crypto.createHash('sha256').update(salt + hashPwd);
}
return hashPwd.digest('hex');
}
//From: http://stackoverflow.com/questions/3745666/how-to-convert-from-hex-to-ascii-in-javascript
function hex2a(hexx) {
var hex = hexx.toString();//force conversion
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
上述输出收率:
52cfd2b127266c1c846ded37c986d8663506118332437daa6eadbc32525c2aa4
52cfd2b127266c1c846ded37c986d8663506118332437daa6eadbc32525c2aa4
虽然以下代码返回预期的结果:
const crypto = require('crypto');
console.log(hashPwd('abc', '11111111111111111111111111111111'));
console.log(hashPwd('def', '11111111111111111111111111111111'));
function hashPwd(password, hexSalt){
const hasher = crypto.createHash('sha256');
var salt = hex2a(hexSalt);
var hashPwd = hasher.update(salt + password);
for(var x =0; x < 199; x++){
hashPwd = hasher.update(salt + hashPwd);
}
return hashPwd.digest('hex');
}
//From: http://stackoverflow.com/questions/3745666/how-to-convert-from-hex-to-ascii-in-javascript
function hex2a(hexx) {
var hex = hexx.toString();//force conversion
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
产生了正确的:
05525f74c0220924a2c9626ca75c2d997bf8b49a8c74208501aaf7a222d11899
c846cb3dc58163530b7b7afc7b467c104fa11566f405b333d030e5e6595bfaec
有人能解释为什么吗?
您可以只用看的
crypto.createHash('sha256').update('abc')+'123'
> '[object Object]123'
当您尝试将字符串添加到您的哈希对象的结果看,你是铸造哈希为一个字符串,这将导致该字符串常量。
如果您使用
hashPwd = crypto.createHash('sha256').update(salt + hashPwd).digest('hex')
这将正常工作。
所以基本上你只是一次又一次地散列字符串salt+'[object Object]'
。
这对于第一个代码示例失败的原因非常有用。但是,如果是这样的话,为什么第二个代码示例给了我看起来好的结果呢?它不应该做同样的事情吗? – Doug
第二个更新使用实际的密码。之后,你只是用无用的字符串更新。但是,第一个散列会使内部状态不同 –
在半相关说明中,如果您控制所有内容,则不应使用纯哈希表示密码。相反,考虑使用类似bcrypt(或可能是scrypt或pbkdf2)。 – mscdex
@mscdex谢谢你的建议。我实际上是从bcrypt开始的,但是我使用的前几个库在Windows上并不能很好地运行。对于这个特定的应用程序,200次迭代的sha256确实应该足够了。我显然需要解决我的错误,所以这是正确的。 – Doug