Spring Security封装了如PBKDF2 , scrypt, Argon2,bcrypt等主流适应性单向加密方法,支持不同的密码加密方式,而且根据不同的用户可以使用不同的加密方式。
/*** 密码编码器*/@Resourceprivate PasswordEncoder passwordEncoder;
目前PasswordEncoder只提供了三个接口方法,具体用法如下;
//encode()是对字符串进行加密的方法,一般对密码进行加密时调用;String encode(CharSequence rawPassword);//使用来校验传入的明文密码rawPassword是否和加密密码encodedPassword相匹配的方法,//一般登录认证时调用;boolean matches(CharSequence rawPassword, String encodedPassword);//upgradeEncoding()是重新编码密码;default boolean upgradeEncoding(String encodedPassword) {return false;}
可以看到,下面这个encode()方法中先得到了一个盐值加盐,并且进行hash加密,所以每次得到的密文都不一样,保证了加密后的安全性
public String encode(CharSequence rawPassword) {if (rawPassword == null) {throw new IllegalArgumentException("rawPassword cannot be null");} else {String salt = this.getSalt();return BCrypt.hashpw(rawPassword.toString(), salt);}}
小结
PasswordEncoder使用哈希算法+随机盐来对字符串加密。因为哈希是一种不可逆算法,所以密码认证时需要使用相同的算法+盐值来对待校验的明文进行加密,然后比较这两个密文来进行验证。BCryptPasswordEncoder在加密时通过从传入的salt中获取real_salt用来加密,保证了这一点。