关于node.js:比较两个密码哈希值 – nodejs

Compare two password hashes — nodejs

我正在使用加密https://nodejs.org/api/crypto.html进行密码加密和身份验证。我正在"更改密码"页上工作,确定用户提供的密码是否与现有密码具有相同的哈希值时遇到问题。下面是我的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
var createSalt=function createSalt() {
    return crypto.randomBytes(128).toString('base64');
};

var hashPwd = function hashPwd(salt, pwd) {
    var hmac = crypto.createHmac('sha256', salt);
    return hmac.update(pwd).digest('hex');
};

//use password , create salt, hash and compare with the existing
var salt=createSalt();
var passHash = hashPwd(salt,data.Password);
console.log('the password is', user.PassHash === passHash);

我希望上面的控制台消息在现有用户密码匹配的地方打印为真。然而,这两个哈希值似乎根本不匹配。请问我缺什么?如何做到这一点?我想在用户更改新密码之前确保其密码与现有密码匹配。任何帮助都将不胜感激。


我认为你的问题在于盐。通常,您必须存储第一次用于散列的盐,然后在第二次使用它。salt的原因是,如果某个黑客从一个被破坏的系统(使用彩虹表攻击)中取回它,那么确保哈希不会映射到原始通行证。明白为什么我们要用"salt"来保护我们的密码吗?

如果你想试试

1
2
3
4
5
6
7
8
9
10
var salt=crypto.randomBytes(128).toString('base64');

var hashPwd = function hashPwd(salt, pwd) {
    var hmac = crypto.createHmac('sha256', salt);
    return hmac.update(pwd).digest('hex');
};

//use password , create salt, hash and compare with the existing
var passHash = hashPwd(salt,data.Password);
console.log('the password is', user.PassHash === passHash);

只要您不重新启动服务器(假设您将saltvar存储在调用以响应HTTP请求的函数范围之外),它就可以工作。

更好的解决方案(IMO)是BCRYPT正在做的。在这里,您为每个密码生成一个salt,但是为了验证密码是否正确,您使用compare,它使用存储在哈希中的salt。通过这种方式,您可以在每个密码中使用不同的盐,这意味着您不必太担心盐被泄露。

1
npm install bcrypt

1
2
3
4
5
var bcrypt = require('bcrypt');
var hash = bcrypt.hashSync("my password");

bcrypt.compareSync("my password", hash); // true
bcrypt.compareSync("not my password", hash); // false

还有compareAsync和其他异步变体。另请参见:https://www.npmjs.com/package/bcrypt-nodejs


1
2
3
4
5
6
7
 UserSchema.pre('save', function (next) {
  if (this.password) {
    const salt=bcrypt.genSaltSync(10);//or your salt constant
    this.password = bcrypt.hashSync(this.password, salt);
  }
  next();
});

in your controller

1
2
3
4
5
6
  const result = bcrypt.compareSync(req.body.password, your_hash_password);
      if (result){
        return res.json(message:"success");
      } else {
        return res.status(400).json("Bad request. Password don't match");
      }