存储哈希密码

时间:2013-07-25 19:37:12

标签: java shiro bcrypt

我需要修改安全登录代码:

@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.");
    }
}

在DAO级别:

  • 使用用户名和散列密码
  • 获取用户对象

但是,现在,存储在数据库中的密码很简单,我只是用散列密码替换它。这里的问题是:

  • BCrypt.hashpw()方法生成不同的哈希,因为我在记录此代码时可以看到。

所以问题是如何在每次更改时存储哈希密码。

我在想的是

  • 用户在UI中输入普通密码,在此登录方法中,密码将被哈希,然后通过fetchUserByName(用户名,哈希)方法获取用户;但它似乎不是这个特殊的Shiro和BCrypt组合的解决方案。

解决这个问题的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

BCrypt.hashpw方法不会为多次迭代返回相同的密码哈希值。

您需要使用BCrypt类的checkpw方法比较不同的哈希密码(一个是新创建的,一个是数据库中的。)

BCrypt.gensalt()在您的方法中正确使用。 只需根据用户名检索用户信息,并使用checkpw方法比较散列密码。

我希望它有所帮助。

答案 1 :(得分:3)

您应该知道hashpw()产生的“哈希密码”不仅仅是哈希。它还包含以明文形式传递的随机生成的盐。

BCrypt.checkpw(password, storedHash)是检查存储哈希的正确方法。该方法将从“散列密码”中检索salt,对明文密码进行散列,并将结果与​​storedHash的实际散列部分进行比较。

您可以找到有关如何使用库here的详细说明。

在你的情况下,我会写这样的方法:

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;
}