这是我当前的密码散列代码并保存到数据库:
var config = {
hashBytes: 64,
saltBytes: 64,
iterations: 8000
};
crypto.randomBytes(config.saltBytes, function(err, salt) {
crypto.pbkdf2(password, salt, config.iterations, config.hashBytes,
function(err, hash) {
var combined = new Buffer(hash.length + salt.length + 8);
combined.writeUInt32BE(salt.length, 0, true);
combined.writeUInt32BE(config.iterations, 4, true);
salt.copy(combined, 8);
hash.copy(combined, salt.length + 8);
callback(combined);
});
});
代码的目标是将salt与哈希一起保存到数据库中的一个字段。这是否可以在数据库中的相同字段中存储密码/ salt?我很久以前就找到了这个算法,现在我不确定我是否理解这一点。
据我所知,首先我们创建一个缓冲区,它有足够的空间来存储哈希,盐,迭代次数和盐长度(不知道为什么我们在这里加8):
var combined = new Buffer(hash.length + salt.length + 8);
然后我们将盐长度字节保存到位置0:
combined.writeUInt32BE(salt.length, 0, true);
我们保存迭代位置4(为什么4?):
combined.writeUInt32BE(config.iterations, 4, true);
我们将盐保存到位置8:
salt.copy(combined, 8);
我们将哈希值保存到位置,这是盐的长度加上我们保存迭代次数和盐长度的大小:
hash.copy(combined, salt.length + 8);
答案 0 :(得分:2)
这段代码似乎正在制造一个现在危险的假设,即一个整数是4个字节长,因此两个整数是8个字节。"
在今天的64位世界中,这种假设将不再适用。而且,无论如何,我们都不需要这种复杂程度和字节错误!
更好的(并且,更简单)策略... (源代码示例未显示) ...只是将所有三个值存储为字符串,由已知字符分隔。例如,12:34:5678
用于存储盐长度为12,迭代次数为34,哈希值为5678.存储该值的代码只是连接三个字符串并将它们存储在一个VARCHAR
字段足够大。并且,以类似的方式,首先检索并检查值的代码"分裂"字符串分为三个组成部分(例如使用正则表达式...),将前两个字符串转换为整数,然后继续评估。
出于很多原因这是优选的,其中最重要的原因是查询数据库的人可以明显地看到这三个部分。 (因此,如果代码中存在某个错误,他/她可以看到错误的后果"一目了然。")
答案 1 :(得分:0)
使用库bcrypt,它很容易生成密码哈希。
npm install --save bcrypt
然后包括库
const bcrypt = require( 'bcrypt' );
以异步方式生成散列使用以下方法。
bcrypt.hash( 'passwordToHash', 10, function( err, hash ) {
// Store hash in database
});
10
是生成salt时要使用的轮数。
验证密码
bcrypt.compare( 'passwordToCompare', hash, function( err, res ) {
if( res ) {
// Password matched
} else {
// Password didn't match
}
});
以同步方式生成和验证哈希使用以下方法。
let hash = bcrypt.hashSync( 'passwordToHash', 10 );
10
是生成salt时要使用的轮数。验证哈希
if( bcrypt.compareSync( 'passwordToCompare', hash ) ) {
// Password matched
} else {
// Password didn't match
}