Spring Security的密码加密策略你真的用对了么?

Java 0 1655

先领略网上各种开源项目千篇一律的配置

@Bean
public PasswordEncoder passwordEncoder() {  
    return new BCryptPasswordEncoder();
}

不对么? 呃...对, 截止到我写文章时的版本5.3时依然没问题. 但绝对不是最佳实践. 为什么? 那就要先看看Spring Security现存的几个没有标记为 deprecatedPasswordEncoder 了.

PasswordEncoder

1. DelegatingPasswordEncoder
2. BCryptPasswordEncoder
3. Argon2PasswordEncoder
4. Pbkdf2PasswordEncoder
5. SCryptPasswordEncoder

Encoder 就不一一介绍了, 可自行阅读官方文档. 点我直达

这里只谈谈 DelegatingPasswordEncoder 随着计算机硬件的不断强大, 算力越来越高. 很多加密算法可能随着时代前进在当时看来很可靠的算法可能会变的不再那么安全. 或是出现更优的加密方式. 这会产生两个问题:

  1. 密码存储的最佳做法将再次更改
  2. 有许多使用旧密码编码的应用程序无法轻松迁移

并且作为一个框架,Spring Security 不能经常进行重大更改. 所以 Spring Security 引入了DelegatingPasswordEncoder解决了以下问题:

DelegatingPasswordEncoder 会基于前缀委托给另一个 PasswordEncoder 的密码编码器.例如:

{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG// 会委托给 BCryptPasswordEncoder
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc// 会委托给 Pbkdf2PasswordEncoder

截止目前 5.3 版本加密密码会委托给 BCryptPasswordEncoder 加密后的格式例: {bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG 所以网上都在直接配置 BCryptPasswordEncoder 为密码编解码器. 如果以后 Spring Security 升级采用新的 DCryptPasswordEncoder, 你就要手动更新你的配置了, 并且你要考虑之前已存在的编码. 那么为什么不直接用 DelegatingPasswordEncoder 呢? 其实这才是最佳实践:

@Bean
public PasswordEncoder passwordEncoder() {  
    return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

注: 目前不主动指定 PasswordEncoder 则 Spring Security 默认就采用 DelegatingPasswordEncoder.

更详细资料请参考 <<官方文档>>

本文采用 知识共享署名4.0国际许可协议进行许可. 本站文章除注明转载/出处外, 均为本站原创或翻译,转载前请务必署名!