比较两个密码哈希 - nodejs

Nur*_*ihu 5 hash cryptography node.js

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

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);
Run Code Online (Sandbox Code Playgroud)

我期待上面的控制台消息在现有用户密码匹配时打印为true.但是,这两个哈希似乎根本不匹配.请问我错过了什么?怎么做到这一点?我想确保用户密码与他现有的密码匹配后才能更改新密码.任何帮助,将不胜感激.

iwe*_*ein 7

我认为你的问题在于盐.通常,您必须首次存储用于哈希的盐,并在第二次重复使用它.salt的原因是确保哈希不会映射到原始传递,如果某个黑客将从受损系统中检索它(使用彩虹表攻击).请参阅为什么我们使用"盐"来保护我们的密码?

如果你愿意的话

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);
Run Code Online (Sandbox Code Playgroud)

只要您不重新启动服务器,它就会起作用(假设您将saltvar 存储在调用的函数的外部作用域以响应http请求).

bcrypt正在做的更好的解决方案(imo).在那里,您为每个密码生成一个salt,但要验证密码是否正确,您可以使用compare,它使用存储在哈希中的salt.这样,您可以在每个密码中使用不同的盐,这意味着您不必担心受到损害的盐.

npm install bcrypt
Run Code Online (Sandbox Code Playgroud)

...

var bcrypt = require('bcrypt');
var hash = bcrypt.hashSync("my password");

bcrypt.compareSync("my password", hash); // true
bcrypt.compareSync("not my password", hash); // false
Run Code Online (Sandbox Code Playgroud)

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

  • 您不应该将哈希值与对计时攻击敏感的“===”进行比较。使用“crypto.timingSafeEqual” (4认同)