Comparing Bcrypt Hash Between PHP and Nodejs

Comparing BCrypt hash between PHP and NodeJS

This fails because the types of bcrypt hashes being generated from php and node are different. Laravel generates the $2y$ while node generates the $2a$. But the good news is the only difference between 2a and 2y are their prefixes.

So what you can do is make one of the prefix similar to the other. Like:

$phpGeneratedHash  = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2a$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';

To something like:

$phpGeneratedHash  = '$2y$10$jOTwkwLVn6OeA/843CyIHu67ib4RixMa/N/pTJVhOjTddvrG8ge5.';
$nodeGeneratedHash = '$2y$10$ZiBH5JtTDtXqDajO6f4EbeBIXGwtcGg2MGwr90xTH9ki34SV6rZhO';

Notice that I replaced the $2a$ of the node hash to $2y$. You can simply do this with:

PHP

$finalNodeGeneratedHash = str_replace("$2a$", "$2y$", $nodeGeneratedHash);

Node

finalNodeGeneratedHash = nodeGeneratedHash.replace('$2a$', '$2y$');

Then compare phpGeneratedHash to finalNodeGeneratedHash.

Note: It is recommended that if you're comparing in PHP, change the prefix of the NodeJS generated hash to $2y$ and if you're comparing in NodeJS; change the prefix of the PHP generated hash to $2a$.

Compare Nodejs generated bcrypt hash in PHP

You shouldn't expect them to match, at least by default. This is because for both functions, a random salt is chosen every time you hash a value.

The important thing is not that the hash outputs match, but that they still validate. So you could take the hashed output from node.js and use it with password_verify() in PHP for example, and it should validate.

How to verify a PHP hashed password in a NodeJS app

Use bcryptjs package instead. It can compare php generated hashes correctly.

const bcrypt = require('bcryptjs')

const hashPHP = "$2y$10$Lsn001yN38WssfQmJ5hM5.Ywa3AKB76YD/zUC9QNS5BPRr9QMWOTa"
console.log(bcrypt.compareSync("my password", hashPHP)); // outputs: true

bcrypt hashing vs comparing on user login

I will provide an alternative answer to the already approved answer, with emphasis on security...

As the email is unique, I would first find the user based on the email alone, get the password from the retrieved user, and compare these using bcrypt. If the email exists, but the password doesn't match, there may be a brute force attack in place, you may want to log these failed attempts so you can lock accounts or add a captcha perhaps to slow down/prevent the attack.

How is this different

ORIGINAL SOLUTION

  1. Get the user from the email and hashed password
  2. If the credentials are right, great, the user can log in. No problems here
  3. If the user is not found, was the email or password incorrect? You can't know with this one query alone.
  4. The potential attacker is free to continue trying to access a potential account by trying different passwords on the inputted email.

ALTERNATIVE SOLUTION

  1. Get the user from the email alone
  2. If the user exists, compare the hashed user password in the DB with the hash password of the inputted credentials (using bcrypt compare).
  3. If the password is incorrect, log this in another table (USER_FAILED_LOGINS), after 3 failed attempts, add a some security measure such as a captcha.
  4. If the password is correct, great, log the user in.

You could of course, use the original solution and just do another query if the credentials were incorrect to figure out if the email exists and implement the security measures at this point. Just be wary of these types of attacks and prevent against them. Also, make sure you are using prepared statements in your SQL.

bcrypt compare with nodejs

Hi bro first we hashed password and stored in db right

retrieve that hashed password from db and compare it with actual password

for eg: if we trying to login with email and password

    User.find({email:req.body.email}).exec().then(result=>{

if(result.length < 1){
console.log('email not found')
}else{
bcrypt.compare(req.body.password,result[0].password,(err,result)=>{
if(err){
console.log('password not match')
}
if(result){
console.log('password match')
}
})
}
})

how to compare bcrypt hash password

bcrypt has a built-in method for comparing hashes.

async function passCheck(event) {
var fromDB = await pool.query('SELECT password from User WHERE email = ? Limit 1', event.emailID);
// --------------------------------------------------------------------------^
// Added limit 1 to make sure the only one record will be returned.
if (fromDB.length > 0 && await bcrypt.compare(event.password, fromDB[0].password)) {
//Here i am comparing
console.log('valid');
} else {
console.log('invalid');
}
}

DB result sets usually returns an array of objects, therefore, you should check that there are some results (fromDB.length > 0) and then pass to the compare method the hashed string itself.

nodejs - bcrypt: compare hash with password always return not match

 query = "insert query with generated crypt password";

That should be query = "insert query with generated hash" because bcrypt.hash() gives a hash as seen in the method parameter :
function(err, hash) so this callback receives either an error or a hash

There's an interesting question on how bcrypt compare works



Related Topics



Leave a reply



Submit