2016-05-17 184 views
4

我使用密码https://nodejs.org/api/crypto.html进行密码加密和身份验证。我正在修改密码页面,并且在确定用户提供的密码是否与现有密码相同时存在问题。以下是我的代码。比较两个密码哈希值 - nodejs

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

我在等待上面的控制台消息打印真实的地方,现有的用户密码匹配。但是,这两个哈希似乎完全不匹配。请问我错过了什么?如何做到这一点?我想确保用户密码与他现有的密码匹配,然后他可以更改新的密码。任何帮助,将不胜感激。

回答

4

我认为你的问题是在盐。通常你必须储存你第一次使用的哈希值,并且第二次重复使用它。盐的原因是为了确保散列不映射到最初的通行证,如果一些黑客从受损系统检索它(使用彩虹表攻击)。见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。通过这种方式,您可以对每个密码使用不同的盐,这意味着您不必担心盐会被泄漏。

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

+0

哦谢谢iwein,所以我应该使用相同的盐的权利。我的意思是代替创建新盐,我应该使用现有密码中的一个。 ? –

+0

@NuruSalihu是的,这就是我的理解。如果你的盐被盗,你必须重置所有密码并重新生成盐。通常加密库允许你比较一遍而不再传递一个盐(他们将盐存储在散列传递中)。 bcrypt这样做例如http://stackoverflow.com/questions/6832445/how-can-bcrypt-have-built-in-salts – iwein

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