Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bcrypt.compare always returns false #906

Open
francis-Paul-code opened this issue Dec 13, 2021 · 19 comments
Open

bcrypt.compare always returns false #906

francis-Paul-code opened this issue Dec 13, 2021 · 19 comments

Comments

@francis-Paul-code
Copy link

francis-Paul-code commented Dec 13, 2021

Of course many have had the challenge but I've looked at most solutions and I still can't find the reason why my case has refused.

Screenshot from 2021-12-13 20-12-22

I've checked everything thoroughly, the characters saved in the DB are the exact Hash character length, the passwords are the same, I just cannot understand why It refuses to work

@jonbito
Copy link

jonbito commented Dec 21, 2021

Ensure you aren't hashing more than once. Are you hashing in an ORM model update?

@irkhamissimo
Copy link

This might be happened because of character length in your DB. Check this

@edersonfaccin
Copy link

In my case, happened using windows, but the same project using a mac, works

Any solution?

@Gatharikih
Copy link

I'm also experiencing the same issue. The problem is neither due to rehashing nor using different character sets.

@borjamunozvw
Copy link

Here I'm facing the same problem with compareSync (is always returning false). But, in my case, when I change compareSync with compare, return true in every case.

image

@mosesrb
Copy link

mosesrb commented Feb 9, 2023

I am having the same issue, anyone got the around it?

@Gatharikih
Copy link

Personally I'd to create a REST API in Java to hash and compare passwords.

@borjamunozvw
Copy link

borjamunozvw commented Feb 13, 2023

For me the solution was to hashing the password and then compare it. It seems that the bycrypt.compare only works with the original password and the hashed pasword:

 if (!user) {
    console.log("user not found");
    return res.send("user not found!");
  } else {
    bcrypt.hash(req.body.password, 10, function (err, hash) {
      if (err) {
        throw err;
      } else {
        bcrypt.compare(user.password, hash, function (err, result) {
          if (err) {
            throw err;
          }
          console.log(result);
          if (!result) {
            return res.status(201).json({ message: "Wrong password!" });
          } else {
            return res.status(201).json({ message: "Connected!", user: user });
          }
        });
      }
    });
  }

@mosesrb
Copy link

mosesrb commented Feb 13, 2023

For me the solution was to hashing the password and then compare it. It seems that the bycrypt.compare only works with the original password and the hashed pasword:

 if (!user) {
    console.log("user not found");
    return res.send("user not found!");
  } else {
    bcrypt.hash(req.body.password, 10, function (err, hash) {
      if (err) {
        throw err;
      } else {
        bcrypt.compare(user.password, hash, function (err, result) {
          if (err) {
            throw err;
          }
          console.log(result);
          if (!result) {
            return res.status(201).json({ message: "Wrong password!" });
          } else {
            return res.status(201).json({ message: "Connected!", user: user });
          }
        });
      }
    });
  }

The code above takes the plaintext password and hashes it and then uses bcrypt compare method over it. So every password is a valid password because you are not testing it against the stored password in database but rather with user own password.

@mosesrb
Copy link

mosesrb commented Feb 13, 2023

Something is up with my MongoDB idk, tried argon2 npm as well and even that package is unable to verify password from MongoDB, below is my password field schema, am i doing something wrong here before storing data in MongoDB

const userSchema = new mongoose.Schema({ name:{ type: String, minlength: 3, maxlength: 255, required: true }, email:{ type: String, minlength: 3, maxlength: 255, unique: true, required: true }, password:{ type: String, minlength: 3, maxlength: 1024, required:true }, isAdmin: Boolean });

@borjamunozvw
Copy link

For me the solution was to hashing the password and then compare it. It seems that the bycrypt.compare only works with the original password and the hashed pasword:

 if (!user) {
    console.log("user not found");
    return res.send("user not found!");
  } else {
    bcrypt.hash(req.body.password, 10, function (err, hash) {
      if (err) {
        throw err;
      } else {
        bcrypt.compare(user.password, hash, function (err, result) {
          if (err) {
            throw err;
          }
          console.log(result);
          if (!result) {
            return res.status(201).json({ message: "Wrong password!" });
          } else {
            return res.status(201).json({ message: "Connected!", user: user });
          }
        });
      }
    });
  }

The code above takes the plaintext password and hashes it and then uses bcrypt compare method over it. So every password is a valid password because you are not testing it against the stored password in database but rather with user own password.

Sorry that I didn't copy the full code so it the can be tricky. In my case "user.password" was the equivalent to my database user (as you can see, I've declared and array with users), and not the received through body (I also checked with postman). Here you can find the full code:


const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");

function login(req, res) {
  // console.log('username', req.body.username)
  // console.log('password', req.body.password)
  const users = [
    {
      id: "kasndaojsdnasd",
      username: "usuario1",
      password: "pwusuario1",
    },
    {
      id: "kasasdasdasd",
      username: "usuario2",
      password: "pwusuario2",
    },
    {
      id: "asdasdnasd",
      username: "usuario3",
      password: "pwusuario3",
    },
  ];
  //modify for the proper db service
  const user = users.find((user) => user.username == req.body.username);

  if (!user) {
    console.log("user not found");
    return res.send("user not found!");
  } else {
    bcrypt.hash(req.body.password, 10, function (err, hash) {
      if (err) {
        throw err;
      } else {
        bcrypt.compare(user.password, hash, function (err, result) {
          if (err) {
            throw err;
          }
          console.log(result);
          if (!result) {
            return res.status(201).json({ message: "Wrong password!" });
          } else {
            return res.status(201).json({ message: "Connected!", user: user });
          }
        });
      }
    });
  }
}

module.exports = login;

I've tested with both correct and incorrect password and username and works in every case

@recrsn
Copy link
Collaborator

recrsn commented Feb 13, 2023

@borjamunozvw your code here is incorrect; bcrypt expects compare(data, hash)

  • Data = user input
  • hash = hashed password from db

For others with this issue, unless someone provides me with a sample repository and some DB dump, I'll not be able to work on this case. I'm unable to reproduce this at my side.

@mosesrb
Copy link

mosesrb commented Feb 13, 2023

@borjamunozvw Yes you are right the 'user' is from database, however the

bcrypt.compare() require plaintext and hash password from database.

bcrypt.compare(plaintext, hashpassword)

and i also tried your code but it's still giving me false every time.

@mosesrb
Copy link

mosesrb commented Feb 13, 2023

@recrsn I am using node@16.14.2 along with mongoose@6.9.1 with mongoDB compass. I have no idea why compare method is not working. I tried argon2 npm as well. The verify method in that package is also not working with my setup.

I think something is wrong with my database, I have increased the limit to 2048 char for password but still it's not working

@SuhailHamid42
Copy link

I had also same problem and finally I realised that we first have to save the one user and password will be encrypted and then compare will work properly. I did it and my problem was solved. If you have users in the db whose passwords aren't encrypted then compare will always return false.

@Gatharikih
Copy link

I had also same problem and finally I realised that we first have to save the one user and password will be encrypted and then compare will work properly. I did it and my problem was solved. If you have users in the db whose passwords aren't encrypted then compare will always return false.

For avoidance of doubt, am comparing user's encrypted password stored in db against the user's provided password.

@Forium777
Copy link

Same issue. Seems to always returns false. Database column is enough large, tried to change $2b$ to $2a$ without chance, tried to use compare() instead of compareSync() but all same. Still returning false...

Any workaround?

@vamshizz
Copy link

I had also same problem and finally I realised that we first have to save the one user and password will be encrypted and then compare will work properly. I did it and my problem was solved. If you have users in the db whose passwords aren't encrypted then compare will always return false.

for me same issue how to solve

@PACMainArchitect
Copy link

This might be happened because of character length in your DB. Check this

Thank's a lot, you saved my day

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

13 participants