使用 Spring 安全、Spring 引导和 MongoDB 进行密码编码和解码

Password encoding and decoding using Spring Security, Spring Boot and MongoDB

我使用上面提到的软件堆栈,我需要在保存到数据库之前加密密码。我还需要解密密码,因为当有人更改密码时,他需要输入旧密码,然后输入两次新密码,我需要检查旧密码。 我搜索了很多,但我仍然不确定什么是正确的方法。 我找到了 link Encrypting 但是还有其他提示吗? 我也不确定 MongoDB 是否提供了一些保护密码的东西。

你根本不应该 "encrypting" 密码。我知道这听起来有悖常理。但是您的系统需要解密密码的理由为零。这样做会向黑客打开您的数据库,因为如果您将解密密码存储在 codes/server 中,黑客就可以窃取该信息。

正确的过程是hash密码。哈希是一种单向(无法解密回原始文本)过程。当前的标准是使用 SHA256 来散列您的密码。这是一个基本流程图:

  1. 获取用户提交的密码。示例密码 "mypass" 将散列为 ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222
  2. 将此哈希 (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.BCryptPasswordEncoderBCryptPasswordEncoder(与 StandardPasswordEncoder 相反)使用每个密码都不同的盐(但不像 StandardPasswordEncoder 中的那样是全局的)。当您对原始密码 (public String encode(CharSequence rawPassword)) 进行编码时,返回的编码密码不仅仅是编码后的密码,它还包含一些关于所使用的哈希算法、使用的 salt,当然还有编码密码的元信息。