Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node bCrypt.compareSync

I am creating a user login. I am able to have the user sign up and when the user sings up his password is encrypted before it is saved in the database.

When that same user tries to log in, I am getting an "invalid password".

This is because it is comparing the user input to an encrypted password in the database. Example if password is 1234, then in database it is saved as "$2a$104$0301". When the user tries to log in, the user input which is "1234" is compared to "2a$104$0301". How would I fix?

Here is my code for login:

var LocalStrategy = require('passport-local').Strategy;
var User = require('../Models/users.js');
var bcrypt = require('bcrypt-nodejs');

module.exports = function(passport){
passport.use('login', new LocalStrategy({
     passReqToCallback : true
 },
    function(req, username, password, done){
        User.findOne({'username' : username},
        function(err, user){
            if(err)
                return done(err);
            if(!user){
                console.log('User Not Found with username: '+username);
                return done(null, false,
                    req.flash('message', 'User Not Found.'));
            }
            if (!isValidPassword(user, password)){
                console.log('Invalid Password');
                return done (null, false,
                    req.flash('message', 'Invalid Password'));
            }
            return done(null, user);
        }
    );
})
);
var isValidPassword = function(user, password){
    var result = bcrypt.compareSync(password, user.password);
    if (result) {
     console.log("Password correct");
    } else {
    console.log("Password wrong");
    }
    return result;

 }
}
like image 921
Suji Avatar asked Jan 02 '15 22:01

Suji


3 Answers

compareSync method takes only 2 arguments and returns a boolean value true or false.

You should perform the check like this:

var result = bcrypt.compareSync(password, user.password);
if (result) {
    console.log("Password correct");
} else {
    console.log("Password wrong");
}
like image 191
Vsevolod Goloviznin Avatar answered Oct 17 '22 19:10

Vsevolod Goloviznin


Really late to the party, however I just had this same problem and the reason it wasn't working for me was that I had encrypted the input password before trying to compare with the already encrypted 'user.password'.

Once I realised there was no need to encrypt the input password, the compareSync worked perfectly.

From bcrypt - npm:

To check a password:

// Load hash from your password DB.
bcrypt.compareSync(myPlaintextPassword, hash); // true
bcrypt.compareSync(someOtherPlaintextPassword, hash); // false

The "compareSync" function counters timing attacks (using a so-called 'constant-time' algorithm). In general, don't use the normal JavaScript string comparison functions to compare passwords, cryptographic keys, or cryptographic hashes if they are relevant to security.

like image 3
Andrew Kwintowski Avatar answered Oct 17 '22 17:10

Andrew Kwintowski


I had a similar problem, when executing bcrypt.compareSync, it did not hash the password of the user who was without bcrypt, the problem was the order in which I had them, which was the following:

bcrypt.compareSync (passwordHash, password)

I solved it by organizing it, first the password and then the passwordHash, which would look like this: bcrypt.compareSync (password, student.password)

I hope it helps someone, good code! <3 @sebasrestrepom

like image 2
Sebastian Restrepo M Avatar answered Oct 17 '22 18:10

Sebastian Restrepo M