2016-05-17 2 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); 

Я ожидаю, если сообщение консоли выше, чтобы напечатать true, когда существующий пароль пользователя совпадает. Однако два хэша, похоже, совсем не совпадают. Пожалуйста, что мне не хватает? Как достичь этого? Я хочу, чтобы пользовательский пароль соответствовал его существующему паролю, прежде чем он сможет изменить новый. Любая помощь будет оценена по достоинству.

ответ

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 вар вне области видимости функции вызываются в ответ на запрос HTTP) ,

Лучшее решение (imo) - это то, что делает bcrypt. Там вы создаете соль за пароль, но для проверки правильности пароля вы используете сравнение, в котором используется соль, хранящаяся в хеше. Таким образом, вы можете использовать разные соли с каждым паролем, а это значит, что вам не нужно беспокоиться о том, чтобы соль была скомпрометирована.

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 да, вот как я это понимаю. Если ваша соль украдена, вам необходимо сбросить все пароли и восстановить соль. Часто crypto libs позволяет вам сравнивать проход без повторной передачи соли (они хранят соль внутри хеширования). 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 "); 
     } 
Смежные вопросы