Spring Security实现密码加密方法
首先,Spring Security提供了强大的加密工具PasswordEncoder,PasswordEncoder接口的代码如下:
public interface PasswordEncoder {
String encode(CharSequence var1);
boolean matches(CharSequence var1, String var2);
default boolean upgradeEncoding(String encodedPassword) {
return false;
}
}
该接口下定义了三个方法,encode是对加密加密方法,而Boolean类型的match方法是用来验证密码和加密后密码是否一致的如果一致则返回true。和authentication.encoding包中的PasswordEncoder接口相比,详细的可以到authentication.encoding包下查找相应的代码,这里就不列举了。
然后,Spring Security提供了BCryptPasswordEncoder类,该类实现了Spring的PasswordEncoder接口,使用BCrypt强哈希方法来对密码进行加密,通过BCrypt强哈希方法每一次加密的结果都不一样,我们可以看看BCryptPasswordEncoder的源码:
public class BCryptPasswordEncoder implements PasswordEncoder {
private Pattern BCRYPT_PATTERN;
private final Log logger;
private final int strength;
private final SecureRandom random;
public BCryptPasswordEncoder() {
this(-1);
}
public BCryptPasswordEncoder(int strength) {
this(strength, (SecureRandom)null);
}
public BCryptPasswordEncoder(int strength, SecureRandom random) {
this.BCRYPT_PATTERN = Pattern.compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}");
this.logger = LogFactory.getLog(this.getClass());
if (strength == -1 || strength >= 4 && strength <= 31) {
this.strength = strength;
this.random = random;
} else {
throw new IllegalArgumentException("Bad strength");
}
}
public String encode(CharSequence rawPassword) {
String salt;
if (this.strength > 0) {
if (this.random != null) {
salt = BCrypt.gensalt(this.strength, this.random);
} else {
salt = BCrypt.gensalt(this.strength);
}
} else {
salt = BCrypt.gensalt();
}
return BCrypt.hashpw(rawPassword.toString(), salt);
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword != null && encodedPassword.length() != 0) {
if (!this.BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
this.logger.warn("Encoded password does not look like BCrypt");
return false;
} else {
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
} else {
this.logger.warn("Empty encoded password");
return false;
}
}
}
毫无疑问,BCryptPasswordEncoder类实现了PasswordEncoder 接口下方法,实现了方法encode,方法encode采用强哈希的BCrypt方式进行加密。
应用,我们在编写用户实体类的时候,可能会对密码password进行加密,这时候我们就可以编写一个加密的方法,例如:
public void setEncodePassword(String password){
//PasswordEncoder是一个接口,而BCryptPasswordEncoder实现了这个接口,里面有一个encode方法是对面进行加密
PasswordEncoder encoder = new BCryptPasswordEncoder();
String encodePWD =encoder.encode(password); //加密完之后赋值给encodePWD
this.password = encodePWD;
}