使用 Spring Security、Spring Boot 和 MongoDB 进行密码编码和解码

Posted

技术标签:

【中文标题】使用 Spring Security、Spring Boot 和 MongoDB 进行密码编码和解码【英文标题】:Password encoding and decoding using Spring Security, Spring Boot and MongoDB 【发布时间】:2016-05-16 06:46:01 【问题描述】:

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

【问题讨论】:

【参考方案1】:

首先阅读 Steven Carlson´s answer 关于密码哈希的内容。

好消息是 Spring Security 会为你做这件事。 Spring Security 3.2 引入了新的org.springframework.security.crypto.password.PasswordEncoder 接口和一些实现:BCryptPasswordEncoderStandardPasswordEncoder(和NoOpPasswordEncoder)。

重要提示:不要将 org.springframework.security.crypto.password.PasswordEncoder 与旧的已弃用 org.springframework.security.authentication.encoding.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)) 进行编码时,返回的编码密码不仅仅是编码密码,它还包含一些关于使用的哈希算法、使用的盐以及编码密码的元信息。

【讨论】:

感谢您添加 Spring 信息,因为我不熟悉该产品 :) 如何获取您提到的元信息,例如使用过的盐? 如果是BCryptPasswordEncoder,元信息就是盐:看看BCrypt.hashpw(String password, String salt)。名为salt 的参数是加密的旧密码。该方法中的代码“读取”密码中的盐【参考方案2】:

您根本不应该“加密”密码。我知道这听起来违反直觉。但是您的系统需要解密密码的理由为零。这样做会将您的数据库向黑客开放,因为如果您将解密密码存储在您的代码/服务器中,黑客就可以窃取该信息。

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

    获取用户提交的密码。示例密码“mypass”将散列到ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222 将此哈希 (ea71c25a7a602246b4c39824b855678894a96f43bb9b71319c39700a1e045222) 存储在您的数据库中。

当用户登录时,您获取他刚刚提交的密码并对其进行哈希处理。如果他输入相同的密码,它将在您的数据库中散列为相同的值。

当用户更改密码时,您对“输入旧密码”进行哈希处理以验证旧密码是否仍然匹配,如果匹配,则对“输入新密码”进行哈希处理并保存。

我在示例中没有提到的一件事是salt。这是您必须在系统中使用的东西,因为它可以保护您的数据免受rainbow table 攻击。但这是另一个讨论。

希望这会有所帮助:)

【讨论】:

嗨@Steven,您在回答中提到,为了比较密码,只需获取密码并对其进行哈希处理并进行比较?通常这个比较会像select * from users where email=? and password=?,因为这个哈希密码会不同,这个匹配是如何工作的? 好的,如果我理解正确,我们将获取具有电子邮件 ID 的用户,然后使用 match 将密码与编码和纯文本进行匹配。

以上是关于使用 Spring Security、Spring Boot 和 MongoDB 进行密码编码和解码的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring-session 和 spring-cloud-security 时,OAuth2ClientContext (spring-security-oauth2) 不会保留在 Redis

未调用 Spring Security j_spring_security_check

Spring security:Spring security 如何在 SessionRegistry 中注册新会话?

在使用 Oauth、SAML 和 spring-security 的多租户的情况下从 spring-security.xml 中获取错误

Spring-Security:升级到 Spring-Security 4.1 后,用户名发送为空以进行登录

Spring mvc / security:从spring security中排除登录页面