使用 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
接口和一些实现:BCryptPasswordEncoder
、StandardPasswordEncoder
(和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.BCryptPasswordEncoder
。
BCryptPasswordEncoder
(与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 中获取错误