2016-05-17 175 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 "); 
     }