使用带有Spring Security Grails插件的BCrypt密码哈希

Dón*_*nal 2 grails spring-security bcrypt grails-plugin

我正在尝试在使用Spring Security插件的Grails应用程序中使用BCrypt密码哈希.我通过添加以下内容启用了BCryptConfig.groovy

grails.plugins.springsecurity.password.algorithm = 'bcrypt'
Run Code Online (Sandbox Code Playgroud)

我已经定义了以下编解码器来简化使用BCrypt来编码密码:

public class PasswordCodec {

    // it doesn't seem to be possible to dependency-inject codecs, so lookup the bean ourselves
    @Lazy
    private static PasswordEncoder passwordEncoder = Holders.grailsApplication.mainContext.getBean('passwordEncoder')

    static encode = { str ->
        passwordEncoder.encodePassword(str.toString(), null)
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在开发模式下启动应用程序时,数据库会使用几个帐户进行自举(每个帐户都有相同的密码,例如

3.times { i ->
    def username = "user$i"
    def password = "secret".encodeAsPassword()

    new User(username: username, password: password).save()
    // also assign the user a role
}
Run Code Online (Sandbox Code Playgroud)

如果我查看数据库,我看到每个用户密码的编码值是不同的!因此,当用户尝试登录并输入"秘密"密码时,BCrypt编码的密码值与数据库中保存的密码值不匹配也就不足为奇了,因为似乎字符串的BCrypt编码值会发生某种变化随着时间的推移.

显然我在这里做错了,但我不知道是什么?

Bur*_*ith 9

在给定相同输入的情况下,密码哈希值通常是相同的(并且偶尔使用不同的输入).但是bcrypt和其他人每次都会生成不同的哈希值.但这不是问题,因为PasswordEncoder接口既有String encodePassword(String rawPass, Object salt)生成哈希的boolean isPasswordValid(String encPass, String rawPass, Object salt)方法,也有验证它们的方法.

使用更简单的哈希值,如MD5,SHA-1等,验证过程只是重新编码明文密码并检查它是否与存储的散列值相同.使用bcrypt这个过程要复杂得多,但最终的结果是相同的 - 它不会检查是否相等,而是它们是等价的.因此,如果您将相同的密码两次哈希并与之进行比较isPasswordValid,则会返回true.