我尝试在使用Spring Security插件的Grails应用中使用BCrypt密码哈希。我已通过将以下内容添加到Config.groovy
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编码值会随着时间的推移而发生变化。
显然我在这里做错了什么,但我不知道是什么?
答案 0 :(得分:8)
在给定相同输入的情况下,密码哈希值通常是相同的(并且偶尔会有不同的输入)。但是bcrypt和其他人每次都会生成不同的哈希值。但这不是问题,因为PasswordEncoder
接口既有String encodePassword(String rawPass, Object salt)
方法来生成哈希值,也有boolean isPasswordValid(String encPass, String rawPass, Object salt)
方法来验证它们。
使用更简单的哈希值,如MD5,SHA-1等,验证过程只是重新编码明文密码并检查它是否与存储的哈希值相同。使用bcrypt的过程要复杂得多,但最终结果是相同的 - 它不会检查相等,而是它们等效。因此,如果您对相同的密码进行两次哈希并将其与isPasswordValid
进行比较,则会返回true
。