如何将散列值与 JavaScript 库 node-password-hash 进行比较?

How to compare hashed values with the JavaScript library node-password-hash?

短版:

我想知道是否使用随机盐对相同的值进行哈希处理,我如何验证我现在得到的值是否 "equal" 与我数据库中已存储为用户的值密码。还有这里的equal是什么意思?

长版:

直到现在,当必须对密码进行哈希处理时,我认为哈希函数是这样工作的:

因此,我在 Node.js

中有以下代码
var passwordHash = require('password-hash');

var foo = passwordHash.generate('password123');
var bar = passwordHash.generate('password123');

console.log(foo); //sha1$d1d19f32$d5cb099afdd9bb130c969e0394c9bf5e57d6a2aa
console.log(bar); //sha1$df372235dfd5485e8a223e21738621bf4a7cdfca949721


console.log(passwordHash.verify('password123', foo)); //true
console.log(passwordHash.verify('password123', bar)); //true

我知道 passwordHash.generate() 使用随机盐,它是 $...$ 之间的部分。我在文档中找不到盐存储在某个地方,如果是,为什么两个散列值不相同?

我认为 passwordHash.verify() 散列 "password123" 并检查它是否与 foobar 相同。然而这不可能发生,因为我总是正确的,但是 foobar 是不同的。

那么 passwordHash.verify() 是如何工作的?

盐包含在 generate 返回的字符串中,由 $ 字符分隔:

sha1$d1d19f32$1$d5cb099afdd9bb130c969e0394c9bf5e57d6a2aa

alg $ salt $ hash

查看密码哈希的源代码,您所要做的就是对包含 $ 和盐的结果字符串调用验证方法。

这是他们的验证函数:

module.exports.verify = function(password, hashedPassword) {
  if (!password || !hashedPassword) return false;
  hashedPassword = makeBackwardCompatible(hashedPassword);
  var parts = hashedPassword.split('$');
  if (parts.length != 4) return false;
  try {
    return generateHash(parts[0], parts[1], password, parts[2]) == hashedPassword;
  } catch (e) {}
  return false;
};

如您所见,它在 $ 上拆分输入字符串,然后生成带有盐的哈希值并与密码进行比较。这意味着您应该使用原始生成方法返回的整个字符串调用验证方法,就像您在问题中所做的那样。