Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare two password hashes -- nodejs

I am using a crypto https://nodejs.org/api/crypto.html for password encryption and authentication. I am working on the change password page and is having problem determining whether the password provided by the user has the same hash as the existing password. Below is my code.

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

I am expecting if the console message above to print true where existing user password match. However, the two hashes does not seem to match at all. Please what am i missing ? How do achieve this? I want to make sure users password match his existing password before he can change a new one. Any help would be appreciated.

like image 811
Nuru Salihu Avatar asked May 17 '16 14:05

Nuru Salihu


People also ask

Is bcrypt better than sha256?

The technology in the Bcrypt algorithm and process limits attacks and makes it harder for attackers to compromise passwords. Bcrypt was not designed for encrypting large amounts of data. It is best implemented for passwords, however SHA-256 is better for large amounts of data because it is less costly and faster.

Should I use bcrypt or Bcryptjs?

Sync functions. Bcrypt is 3.1 times faster than bcryptjs in generating hash passwords and 1.3 times faster in comparing function.


1 Answers

I think your problem is in the salt. Usually you have to store the salt you used to hash the first time and reuse it the second time around. The reason for the salt is to make sure that the hash doesn't map to the original pass if some hacker would retrieve it from a compromised system (using a rainbow table attack). See Why do we use the "salt" to secure our passwords?

If you would try

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

It would work as long as you don't restart the server (assuming you store the salt var outside scope of the function invoked to respond to the http request).

A better solution (imo) is what bcrypt is doing. There you generate a salt per password, but to verify that a password is correct you use compare, which uses the salt stored in the hash. This way you can use different salts with each password, meaning you don't have to worry as much about a salt being compromised.

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

There is also compareAsync and other async variants. See also: https://www.npmjs.com/package/bcrypt-nodejs

like image 99
iwein Avatar answered Sep 24 '22 21:09

iwein