Abdalrahman Shatou
Abdalrahman Shatou

Reputation: 4758

Node's bcrypt Compare Returns False Though It's True

This is driving me crazy. Here is the very simple code:

user = new User(_.pick(userData, ['name', 'email', 'password']));
const salt = await bcrypt.genSalt(15);
user.password = await bcrypt.hash(user.password, salt);
const samePass = await bcrypt.compare(user.password, userData.password);

samePass is always false. I have checked sample request password and the hash on https://bcrypt-generator.com and it does show them matched. bcrypt is always returning false. And you can see that the database has nothing to do with it.

Sample data (I have got both using the IDE debugger with a breakpoint at the samePass line):

user.password = $2b$10$nH2SGNZu9rdyz.V6qpT29eAhxKWfiOIr9ojOi96Ye2lQub.Pglof.
userData.password = oXmZ9pG5T4XtndH%#@A

Upvotes: 3

Views: 5222

Answers (2)

Lionel Rowe
Lionel Rowe

Reputation: 5956

bcrypt.compare takes two parameters: plaintextPassword and hashedPassword, in that order.

$2b$10$nH2SGNZu9rdyz.V6qpT29eAhxKWfiOIr9ojOi96Ye2lQub.Pglof. is a hashed version of oXmZ9pG5T4XtndH%#@A, so you can do this:

const password = 'oXmZ9pG5T4XtndH%#@A'
const preHashedPassword = '$2b$10$nH2SGNZu9rdyz.V6qpT29eAhxKWfiOIr9ojOi96Ye2lQub.Pglof.'

await bcrypt.compare(password, preHashedPassword) // true

You can also do this:

const salt = await bcrypt.genSalt(15)
const newHashedPassword = await bcrypt.hash(password, salt)

await bcrypt.compare(password, newHashedPassword) // true

But you can't do any of these:

await bcrypt.compare(preHashedPassword, newHashedPassword) // false
await bcrypt.compare(newHashedPassword, preHashedPassword) // false
await bcrypt.compare(preHashedPassword, password) // false
await bcrypt.compare(newHashedPassword, password) // false

RunKit demo

Upvotes: 3

kavigun
kavigun

Reputation: 2375

user.password = await bcrypt.hash(user.password, salt); //This line is generating the password hash

While comparing you pass the second argument as password hash stored in the database. But, here in your code, you are overriding the input user.password which contains the actual password which needs to be compared

const samePass = await bcrypt.compare(user.password, userData.password);

Change it to:

let passwordHash = await bcrypt.hash(user.password, salt);
const booleanResult = await bcrypt.compare(userData.password, passwordHash);

Upvotes: 3

Related Questions