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

时间:2016-06-17 22:30:48

标签: node.js hash verify

简短版:

我想知道相同的值是否使用随机盐进行哈希处理,如何验证我现在获得的值是否与我数据库中已存在的值相等,存储为用户密码。这也意味着什么呢?

长版:

到目前为止,我认为当必须对密码进行哈希处理时,哈希函数的工作原理如下:

  • 选择一种算法,假设它是SHA1
  • 使用该算法更改输入,以至于无法猜出输入是什么或看起来如何
  • 将哈希值与用户一起放入数据库中,当需要登录时,再次使用哈希函数输入并将其与数据库中已有的哈希函数匹配
  • 建议使用随机盐,将它们与用户一起存储,在登录阶段,您取出该盐来散列给定的密码并将其与数据库中已有的散列值进行匹配。

所以,我在Node.js中有以下代码

var passwordHash = require('password-hash');

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

console.log(foo); //sha1$d1d19f32$1$d5cb099afdd9bb130c969e0394c9bf5e57d6a2aa
console.log(bar); //sha1$df372235$1$99dfd5485e8a223e21738621bf4a7cdfca949721


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

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

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

那么passwordHash.verify()如何运作?

1 个答案:

答案 0 :(得分:0)

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

SHA1 $ d1d19f32 $ 1 $ d5cb099afdd9bb130c969e0394c9bf5e57d6a2aa

alg $ salt $ hash

查看密码哈希的来源,您应该做的就是在包含$' s和盐的结果字符串上调用verify方法。

这是他们的验证功能:

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;
};

正如您所看到的,它将输入字符串拆分为$,然后使用salt生成散列并与密码进行比较。这意味着您应该使用原始生成方法返回的整个字符串调用verify方法,就像您在问题中一样。