quarks
quarks

Reputation: 35276

Storing hashed password

I need to revamp a secure login code:

@Override
public User login(String username, String password, Boolean rememberMe) {   
    log.info("Logging in username="+username);
    UsernamePasswordToken token;
    String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
    log.info("Hashed password=" + hashed);
    token = new UsernamePasswordToken(username, hashed);
    // ”Remember Me” built-in, just do this:
    token.setRememberMe(rememberMe);
    try {
        // With most of Shiro, you'll always want to make sure you're working with the currently executing user,
        // referred to as the subject
        Subject currentUser = SecurityUtils.getSubject();

        // Authenticate
        //currentUser.login(token);     
        User user = userDAO.fetchUserByName(username, hashed);
        return user;
    } catch (org.apache.shiro.authc.AuthenticationException e) {
        throw new AuthenticationException("Failure in authentication");
    } catch (IllegalStateException e){
        throw new AuthenticationException("Application is in a illegal state");
    } catch (Exception e){
        throw new AuthenticationException("Some other error during login was caught.");
    }
}

At the DAO level:

However, right now, the password stored in the DB is plain, I am just going to replace it with a hashed password. The problem here is this:

So the question would be how to store a hashed password when it changes every time.

The idea that I was thinking is that

What is the right way of dealing with this?

Upvotes: 2

Views: 565

Answers (2)

user684934
user684934

Reputation:

You should be aware that the "hashed password" that results from hashpw() is not just a hash. It also contains the randomly generated salt that you passed in as plaintext.

BCrypt.checkpw(password, storedHash) is the correct way to check against a stored hash. The method will retrieve the salt from the "hashed password", hash the plaintext password, and compare the result to the actual hash portion of storedHash.

You can find a more detailed description of how to use the library here.

In your case, I'd write the method something like this:

public User login(String username, String password) {  
    User user = userDAO.fetchUserByName(username);
    if (!BCrypt.checkpw(password, user.getHash()) 
        throw new AuthenticationException("Failure in authentication");
    return user;
}

Upvotes: 3

PankajSays
PankajSays

Reputation: 1045

BCrypt.hashpw method will not return the same password hash for multiple iterations.

You will need to compare the different hash passwords (one created fresh and one in the database) using checkpw method of BCrypt class.

BCrypt.gensalt() is correctly used in your method. Just retrieve the user information based on the username only and compare the hashed password using checkpw method.

I hope it helps.

Upvotes: 3

Related Questions