问题描述
我正在尝试在使用Spring Security插件的Grails应用中使用BCrypt密码哈希.我通过将以下内容添加到Config.groovy
I'm trying to use the BCrypt password hashing in my Grails app that's using the Spring Security plugin. I've enabled BCrypt by adding the following to Config.groovy
grails.plugins.springsecurity.password.algorithm = 'bcrypt'
并且我定义了以下编解码器,以简化使用BCrypt编码密码的语言:
And I've defined the following codec to simplify using BCrypt to encode paswords:
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)
}
}
当我在开发人员模式下启动应用程序时,数据库会通过几个帐户进行引导(每个帐户都具有相同的密码,例如
When I start the application in dev mode the database is bootstrapped with a few accounts (each of which has the same password, e.g.
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编码值似乎以某种方式发生了变化随着时间的流逝.
If I look in the database, I see that the encoded value of each of these user's password is different! So it's no surprise that when a user attempts to login and enters a password of "secret", the BCrypt-encoded password value doesn't match what's saved in the database, because it seems that the BCrypt-encoded value of a String somehow changes over time.
很显然,我在这里做错了什么,但我不知道该怎么办?
Obviously I'm doing something wrong here, but I've no idea what?
推荐答案
在相同的输入下,密码哈希通常是相同的(偶尔会有不同的输入).但是bcrypt和其他每次都会生成不同的哈希.但是,这不是问题,因为PasswordEncoder
接口既具有String encodePassword(String rawPass, Object salt)
方法来生成哈希,又具有boolean isPasswordValid(String encPass, String rawPass, Object salt)
方法来验证哈希.
Often password hashes are identical given the same input (and very occasionally with different inputs). But bcrypt and others generate a different hash each time. This isn't a problem however, because the PasswordEncoder
interface has both the String encodePassword(String rawPass, Object salt)
method to generate hashes, but also the boolean isPasswordValid(String encPass, String rawPass, Object salt)
method to validate them.
使用MD5,SHA-1等更简单的哈希,进行验证的过程只是简单地对明文密码进行重新编码,并检查其是否与存储的哈希值相同.使用bcrypt的过程要复杂得多,但是最终结果是相同的-它不检查平等,而是检查它们是否等效.因此,如果您对同一密码进行两次哈希处理,然后将其与isPasswordValid
进行比较,则会返回true
.
With simpler hashes like MD5, SHA-1, etc. the process for verification is simply re-encoding the cleartext password and checking that it's the same as the stored hashed value. The process is a lot more complicated with bcrypt, but the end result is the same - it doesn't check for equality, but instead that they're equivalent. So if you hash the same password twice and compare them with isPasswordValid
it will return true
.
这篇关于将BCrypt密码哈希与Spring Security Grails插件结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!