使用 Spring 安全、Spring 引导和 MongoDB 进行密码编码和解码
Password encoding and decoding using Spring Security, Spring Boot and MongoDB
我使用上面提到的软件堆栈,我需要在保存到数据库之前加密密码。我还需要解密密码,因为当有人更改密码时,他需要输入旧密码,然后输入两次新密码,我需要检查旧密码。
我搜索了很多,但我仍然不确定什么是正确的方法。
我找到了 link Encrypting 但是还有其他提示吗?
我也不确定 MongoDB 是否提供了一些保护密码的东西。
你根本不应该 "encrypting" 密码。我知道这听起来有悖常理。但是您的系统需要解密密码的理由为零。这样做会向黑客打开您的数据库,因为如果您将解密密码存储在 codes/server 中,黑客就可以窃取该信息。
正确的过程是hash
密码。哈希是一种单向(无法解密回原始文本)过程。当前的标准是使用 SHA256 来散列您的密码。这是一个基本流程图:
- 获取用户提交的密码。示例密码 "mypass" 将散列为
ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
- 将此哈希 (
ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
) 存储在您的数据库中。
当用户登录时,您获取他刚刚提交的密码并对其进行哈希处理。如果他输入相同的密码,它将散列为您数据库中的相同值。
当用户更改密码时,您会散列 "enter your old password" 以验证旧密码是否仍然匹配,如果匹配,您会散列 "enter your new password" 并保存它。
我在示例中没有提到的一件事是 salt
。这是您必须在系统中使用的东西,因为它可以保护您的数据免受 rainbow table
攻击。但那是另一个讨论。
希望这对您有所帮助:)
首先阅读 关于密码散列的内容。
好处是 Spring 安全会为您做这件事。 Spring Security 3.2 引入了新的 org.springframework.security.crypto.password.PasswordEncoder
interface and some implementations: BCryptPasswordEncoder
, StandardPasswordEncoder
(和 NoOpPasswordEncoder
)。
重要提示:不要将 org.springframework.security.
crypto.password
.PasswordEncoder
与旧的已弃用 org.springframework.security.
[ 混淆=18=].PasswordEncoder
接口(以及实现)具有您需要的两种方法:
public String encode(CharSequence rawPassword)
public boolean matches(CharSequence rawPassword, String encodedPassword)
我推荐使用org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
。
BCryptPasswordEncoder
(与 StandardPasswordEncoder
相反)使用每个密码都不同的盐(但不像 StandardPasswordEncoder
中的那样是全局的)。当您对原始密码 (public String encode(CharSequence rawPassword)
) 进行编码时,返回的编码密码不仅仅是编码后的密码,它还包含一些关于所使用的哈希算法、使用的 salt,当然还有编码密码的元信息。
我使用上面提到的软件堆栈,我需要在保存到数据库之前加密密码。我还需要解密密码,因为当有人更改密码时,他需要输入旧密码,然后输入两次新密码,我需要检查旧密码。 我搜索了很多,但我仍然不确定什么是正确的方法。 我找到了 link Encrypting 但是还有其他提示吗? 我也不确定 MongoDB 是否提供了一些保护密码的东西。
你根本不应该 "encrypting" 密码。我知道这听起来有悖常理。但是您的系统需要解密密码的理由为零。这样做会向黑客打开您的数据库,因为如果您将解密密码存储在 codes/server 中,黑客就可以窃取该信息。
正确的过程是hash
密码。哈希是一种单向(无法解密回原始文本)过程。当前的标准是使用 SHA256 来散列您的密码。这是一个基本流程图:
- 获取用户提交的密码。示例密码 "mypass" 将散列为
ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
- 将此哈希 (
ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
) 存储在您的数据库中。
当用户登录时,您获取他刚刚提交的密码并对其进行哈希处理。如果他输入相同的密码,它将散列为您数据库中的相同值。
当用户更改密码时,您会散列 "enter your old password" 以验证旧密码是否仍然匹配,如果匹配,您会散列 "enter your new password" 并保存它。
我在示例中没有提到的一件事是 salt
。这是您必须在系统中使用的东西,因为它可以保护您的数据免受 rainbow table
攻击。但那是另一个讨论。
希望这对您有所帮助:)
首先阅读
好处是 Spring 安全会为您做这件事。 Spring Security 3.2 引入了新的 org.springframework.security.crypto.password.PasswordEncoder
interface and some implementations: BCryptPasswordEncoder
, StandardPasswordEncoder
(和 NoOpPasswordEncoder
)。
重要提示:不要将 org.springframework.security.
crypto.password
.PasswordEncoder
与旧的已弃用 org.springframework.security.
[ 混淆=18=].PasswordEncoder
接口(以及实现)具有您需要的两种方法:
public String encode(CharSequence rawPassword)
public boolean matches(CharSequence rawPassword, String encodedPassword)
我推荐使用org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
。
BCryptPasswordEncoder
(与 StandardPasswordEncoder
相反)使用每个密码都不同的盐(但不像 StandardPasswordEncoder
中的那样是全局的)。当您对原始密码 (public String encode(CharSequence rawPassword)
) 进行编码时,返回的编码密码不仅仅是编码后的密码,它还包含一些关于所使用的哈希算法、使用的 salt,当然还有编码密码的元信息。