Can't get Bcrypt.checkpw to verify password in java play framework

824 views Asked by At

I have had an application written a few years ago and upgraded some of the jars but not the bcrypt

It is written in java using the play framework.

BCrypt is provided from "org.mindrot" % "jbcrypt" % "0.3m"

I use BCrypt.checkpw(password.trim(), user.getPassword())

where password is the captured plaintext and user.getPassword is the stored hash in mysql stored as char(60).

I hash passwords using BCrypt.hashpw(password.trim(), BCrypt.gensalt(15))

checkpw works interestingly with original passwords but any new ones it fails and always responds false

One interesting observation is I had a password in my dev database which I know is 'password' Its hash looks like this

$2a$10$UvKgjjT./SuMlD6gsoyD0e2lBcOwFtL/mfGmneTou/lrU1R/ZwMLK

vs

a new one I just created and set its password to 'password'

and its hash looks like this

$2a$10$rNJzD52/muHMkBF1Co9XF.VkQNRHQ3HCW.DYzke7jnY424voZwyq6

I know they should differ but the format looks different somewhat?

Please any help appreciated as this makes no sense as nothing has changed but new users cannot register

Code: The password is set within my User class

public void setPassword(String password) {
        play.Logger.debug("setPassword |" + password.trim() +"|");
        this.password = BCrypt.hashpw(password.trim(), BCrypt.gensalt(15));
}

I call this within my register method

public Result registeruser() {
        JsonNode json = request().body().asJson();
.
.
.
        if (json.has("password")) {
          user.setPassword(json.findPath("password").textValue())
        }
.
.
.
       user.save()
.
.
.
}

I then have the following Authenticate method

public static Users authenticate(String email, String password) {
        play.Logger.debug("email is " + email);
        play.Logger.debug("authenticate password entered |" + password.trim() +"|");

        Users user = Users.find.query().where().eq("email", email).findOne();
        if (user != null) {
            play.Logger.debug("password hash from db |" + user.getPassword() +"|");
            Boolean checkPassword = BCrypt.checkpw(password.trim(), user.getPassword());
            play.Logger.debug("checkPassword " + checkPassword);
            if (checkPassword) {               
                    return user;
            } else {
                    return null;
            }
       }
}

Relevant debug output from running

In setPassword part
[debug] application - setPassword |password|

in authenticate part
[debug] application - authenticate password entered |password|
[debug] application - password hash from db |$2a$10$EiuMUWfbCoO.A1GxKk9YeOhqtK0bn4O8Y/W9U/7bEN/CSObOm6jUa|
[debug] application - checkPassword false
1

There are 1 answers

0
user4447899 On

The reason for this was in setPassword was not the right place to do the hashing and I kept getting a blank hashpw. This used to work in the earlier version of play but clearly not anymore

I moved it to a @PrePersist method as follows:

@PrePersist
    public void hashPassword(){
        play.Logger.debug("hashPassword |" + this.password +"|");
        String hashed = BCrypt.hashpw(this.password, BCrypt.gensalt(15));
        play.Logger.debug("hashed " + hashed);
        this.password = hashed;
    }

Problem was solved