使用弹簧安全编码密码的问题
Posted
技术标签:
【中文标题】使用弹簧安全编码密码的问题【英文标题】:Issue in encoding password with spring security 【发布时间】:2013-10-30 04:03:09 【问题描述】:我正在使用 grails 2.3.0 并且在使用 spring security 对密码进行编码时遇到了奇怪的问题:
这是我的密码编码方法:
String encodePassword(String password)
return springSecurityService.encodePassword(password)
这样使用
log.debug encodePassword("mkb")
log.debug encodePassword("mkb")
log.debug encodePassword("mkb")
我多次对同一个密码进行编码,每次都得到不同的编码密码。
日志:
$2a$10$h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K
$2a$10$a7qybaiLF/eNrTSwFohjkezNaJTTDdMEinRYKjxDzEt.OoxaIgFOu
$2a$10$nZVhUT0QTmmbtt22CPtM..cLxU252RGBIMkd5aSd2AFXNTNLQ./6u
【问题讨论】:
【参考方案1】:没关系。看起来您正在使用 BCrypt 密码哈希,每次您对密码进行编码时,此算法都会使用随机盐(其他哈希算法使用“盐源属性”,如 id)。这种盐是预先散列的
所以你有:
$2a
- 盐版
$10
- 回合
$h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K
- 用于 salt+hash 的 Base64,其中 salt 获取前 24 个字符,hash 获取其余字符:
h8T4BxgOeozmH/VSPJl7NeTaF
- 盐
2P0iONpSdqDN7dDFFAG.sy8WG/8K
- 哈希(盐 + 密码 10 轮)
查看 Spring Security 的 BCrypt 来源:https://github.com/spring-projects/spring-security/blob/master/crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java
如果您需要手动检查用户密码,您必须使用passwordEncoder
,例如:
//dependency injection
def passwordEncoder
//validate
String enteredPassword = params.password
User user = ...
if (!passwordEncoder.isPasswordValid(user.password, enteredPassword, null)) //validates raw password against hashed
//... wrong password entered
【讨论】:
为什么要这样做?对密码进行哈希处理并且您可以登录还不够吗? 我正在实现密码重置功能,我需要使用用户输入的当前密码检查我当前保存的密码。 感谢@Igor 和@Burt。passwordEncoder.matches
在我的情况下不起作用(我已经注入了 passwordEncoder bean),可能是我做错了什么。 passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null)
给了我想要的结果。
抱歉,刚刚发现 matches
来自 SS 版本 3.1。该插件使用 SS 3.0。顺便说一句,passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null)
不能与存储的密码进行比较,也许你的意思是 passwordEncoder.isPasswordValid(user.password, 'mkb', null)
?
是的,你是对的,我的意思是passwordEncoder.isPasswordValid(user.password, 'mkb', null)
。 passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null)
仅用于测试。再次感谢。【参考方案2】:
Grails spring security 描述了更新密码的过程:https://grails-plugins.github.io/grails-spring-security-core/4.0.x/index.html
User user = User.findByUsername(username)
if (!passwordEncoder.matches(password, user.password))
flash.message = 'Current password is incorrect'
render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
return
if (passwordEncoder.matches(password_new, user.password))
flash.message = 'Please choose a different password from your current one'
render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
return
其中 password 或 new_password 是参数或方法参数
【讨论】:
以上是关于使用弹簧安全编码密码的问题的主要内容,如果未能解决你的问题,请参考以下文章