我使用加密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);
我期待上面的控制台消息在现有用户密码匹配时打印为true。但是,这两个哈希似乎根本不匹配。请问我错过了什么?怎么做到这一点?我想确保用户密码与他现有的密码匹配后才能更改新密码。任何帮助,将不胜感激。
答案 0 :(得分:6)
我认为你的问题存在于盐中。通常,您必须首次存储用于哈希的盐,并在第二次重复使用它。盐的原因是为了确保哈希不会映射到原始传递,如果某个黑客从受损系统中检索它(使用彩虹表攻击)。见Why do we use the "salt" to secure our passwords?
如果你试试
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);
只要您不重新启动服务器,它就会起作用(假设您将salt
var存储在调用的函数范围之外以响应http请求。)
更好的解决方案(imo)就是bcrypt正在做的事情。在那里,您为每个密码生成一个salt,但要验证密码是否正确,您可以使用compare,它使用存储在哈希中的salt。通过这种方式,您可以在每个密码中使用不同的盐,这意味着您不必担心受到损害的盐。
npm install bcrypt
...
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 :(得分:0)
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();
});
控制器中的
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 ");
}