从 MD5 切换到具有 Spring 安全性的 BCrypt
Switching from MD5 to BCrypt with Spring Security
到目前为止,我的应用程序使用简单的 MD5 算法对用户密码进行哈希处理,现在我们已经在应用程序中引入了 Spring 安全性,并且更愿意使用 BCrypt。我的问题是如何将旧密码迁移到新算法。
- 我可以为 Spring 安全提供多个密码编码器,以便
它们可以轮流使用吗?
- 登录成功后如何更改密码,因为密码是通过SHA1算法传输的?
对于问题 1,我相信使用 CustomAuthenticationProvider 可能有效,但我完全不知道如何在我们的系统中使用它。下面是我来自 SecurityConfig class
的 configureGlobal 函数
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder)
.usersByUsernameQuery("SELECT uname AS username, upwd AS password, true AS enabled FROM user_table WHERE uname!='' AND uname IS NOT NULL AND uname=?")
.authoritiesByUsernameQuery("SELECT uname AS username, 'Default' AS role FROM user_table WHERE uname!='' AND uname IS NOT NULL AND uname=?");
}
我没有在我的应用程序中使用 UserDetailsService,只提供了上述查询。我已经使用了 CustomUsernamePasswordAutheticationFilter 和 CustomPasswordEncoder 如果这对这个问题有用的话。
谢谢,
您应该能够子类化 BCryptPasswordEncoder
,重写 matches
方法,首先让 BCryptPasswordEncoder
尝试找到匹配项,如果匹配项不成功,则尝试 MD5
与您现有的代码匹配。这样,每个拥有 BCrypt
散列密码并提供正确值的人都将快速登录(由于内置 BCryptPasswordEncoder
逻辑)。拥有旧 MD5
散列密码并提供正确值的每个人也将登录(由于您的自定义代码),但会招致额外的惩罚,即首先经过 BCrypt
匹配。其他人都不会登录,但登录失败路径将招致 MD5
检查的额外惩罚。
与其尝试重新散列现有密码,不如建议用户在您完全切换到 BCrypt
后更改密码,因为新选择的密码将使用 BCrypt
,您将省去匹配 MD5
哈希的麻烦。许多公司过去都这样做过,所以这对用户来说可能并不奇怪。
如果您拥有强大的忘记密码功能,甚至可能根本不匹配 MD5
。您将简单地让使用旧 MD5
散列密码登录的用户失败,并要求他们使用 Forgot Password
功能创建一个新密码(无论如何都会用 BCrypt
加密)。
到目前为止,我的应用程序使用简单的 MD5 算法对用户密码进行哈希处理,现在我们已经在应用程序中引入了 Spring 安全性,并且更愿意使用 BCrypt。我的问题是如何将旧密码迁移到新算法。
- 我可以为 Spring 安全提供多个密码编码器,以便 它们可以轮流使用吗?
- 登录成功后如何更改密码,因为密码是通过SHA1算法传输的?
对于问题 1,我相信使用 CustomAuthenticationProvider 可能有效,但我完全不知道如何在我们的系统中使用它。下面是我来自 SecurityConfig class
的 configureGlobal 函数@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder)
.usersByUsernameQuery("SELECT uname AS username, upwd AS password, true AS enabled FROM user_table WHERE uname!='' AND uname IS NOT NULL AND uname=?")
.authoritiesByUsernameQuery("SELECT uname AS username, 'Default' AS role FROM user_table WHERE uname!='' AND uname IS NOT NULL AND uname=?");
}
我没有在我的应用程序中使用 UserDetailsService,只提供了上述查询。我已经使用了 CustomUsernamePasswordAutheticationFilter 和 CustomPasswordEncoder 如果这对这个问题有用的话。
谢谢,
您应该能够子类化 BCryptPasswordEncoder
,重写 matches
方法,首先让 BCryptPasswordEncoder
尝试找到匹配项,如果匹配项不成功,则尝试 MD5
与您现有的代码匹配。这样,每个拥有 BCrypt
散列密码并提供正确值的人都将快速登录(由于内置 BCryptPasswordEncoder
逻辑)。拥有旧 MD5
散列密码并提供正确值的每个人也将登录(由于您的自定义代码),但会招致额外的惩罚,即首先经过 BCrypt
匹配。其他人都不会登录,但登录失败路径将招致 MD5
检查的额外惩罚。
与其尝试重新散列现有密码,不如建议用户在您完全切换到 BCrypt
后更改密码,因为新选择的密码将使用 BCrypt
,您将省去匹配 MD5
哈希的麻烦。许多公司过去都这样做过,所以这对用户来说可能并不奇怪。
如果您拥有强大的忘记密码功能,甚至可能根本不匹配 MD5
。您将简单地让使用旧 MD5
散列密码登录的用户失败,并要求他们使用 Forgot Password
功能创建一个新密码(无论如何都会用 BCrypt
加密)。