Security中PasswordEncoder讲解

Security中PasswordEncoder讲解

      • PasswordEncoder讲解
      • BCryptPasswordEncoder
        • encode(....)实现
        • matches(...)实现
        • 总结
      • MessageDigestPasswordEncoder
      • DelegatingPasswordEncoder
      • NoOpPasswordEncoder

为了适配老系统的安全框架升级,Spring Security也是费劲了心思,支持不同的密码加密方式,而且根据不同的用户可以使用不同的加密方式。

BCryptPasswordEncoder 实现了接口PasswordEncoder

PasswordEncoder讲解

PasswordEncoder是Security提供的一个接口,目前这个接口提供了三个方法,如图
Security中PasswordEncoder讲解_第1张图片
其中encode(…)是对字符串进行加密的方法;matches(…)使用来校验传入的明文密码rawPassword是否和加密密码encodedPassword相匹配的方法。即对密码进行加密时调用encode,登录认证时调用matches。upgradeEncoding(…)是重新编码密码,目前我没用过

BCryptPasswordEncoder

使用BCrypt强哈希方法来加密,不可逆,此类每次进行加密的盐值均不相同,也就是说每次相同的明文加密后的密文均不相同,这样就能保证密码尽量小的被测出来,也是我用得比较多的方式

encode(…)实现

Security中PasswordEncoder讲解_第2张图片
可以看到,这个方法中先基于某种规则得到了一个盐值,然后在调用BCrypt.hashpw方法,传入明文密码和盐值salt。
BCrypt.hashpw方法中先根据传入的盐值salt,然后基于某种规则从salt得到real_salt,后续的操作都是用这个real_salt来进行,最终得到加密字符串。

matches(…)实现

matches方法用来判断一个明文是否和一个加密字符串对应。
Security中PasswordEncoder讲解_第3张图片
这个方法中先对密文字符串进行了一些校验,如果不符合规则直接返回不匹配,然后调用校验方法BCrypt.checkpw,第一个参数是明文,第二个参数是加密后的字符串。
在这里插入图片描述
hashpw(plaintext, hashed)第一个参数是明文,第二个参数是加密字符串,但是在这里是作为盐值salt传入的,所以就用到了刚才说的 hashpw 内部通过传入的salt得到real_salt,这样就保证了对现在要校验的明文的加密和得到已有密文的加密用的是同样的加密策略,算法和盐值都相同,这样如果新产生的密文和原来的密文相同,则这两个密文对应的明文字符串就是相等的。

这也说明了加密时使用的盐值被写在了最终生成的加密字符串中。

总结

BCryptPasswordEncoder使用哈希算法+随机盐来对字符串加密。因为哈希是一种不可逆算法,所以密码认证时需要使用相同的算法+盐值来对待校验的明文进行加密,然后比较这两个密文来进行验证。BCryptPasswordEncoder在加密时通过从传入的salt中获取real_salt用来加密,保证了这一点。

MessageDigestPasswordEncoder

用作传统的加密方式加密(支持 MD5、SHA-1、SHA-256…)

DelegatingPasswordEncoder

最常用的,根据加密类型id进行不同方式的加密,兼容性强

NoOpPasswordEncoder

明文, 不做加密 已废弃

另两种方式用的次数不多,如果有读者有自己的见解欢迎留言

你可能感兴趣的:(技术,java,Security)