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

时间:2014-04-15 17:21:25

标签: grails spring-security grails-plugin bcrypt

我尝试在使用Spring Security插件的Grails应用中使用BCrypt密码哈希。我已通过将以下内容添加到Config.groovy

来启用BCrypt
grails.plugins.springsecurity.password.algorithm = 'bcrypt'

我已经定义了以下编解码器来简化使用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)
    }
}

当我以开发模式启动应用程序时,数据库会被一些帐户引导(每个帐户都有相同的密码,例如

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

    new User(username: username, password: password).save()
    // also assign the user a role
}

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

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

1 个答案:

答案 0 :(得分:8)

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

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