QUESTION:Spring Security使用出現 Encoded password does not look like BCrypt異常的解決以及Spring Securit加密方式的學習?
目錄
QUESTION:Spring Security使用出現 Encoded password does not look like BCrypt異常的解決以及Spring Securit加密方式的學習?
ANWSER:
一:問題提出
博主在做一個SSM整合企業權限管理系統case時,第一次使用spring security框架進行權限驗證,在經過一系列bug的修改,最後邏輯通了,卻出現 Encoded password does not look like BCrypt。查詢半天無果,特此寫下關於spring security框架的學習心得。
之所以出現以上異常,是因爲版本升級5.x後,密碼格式不匹配產生。
我們可以看下拋出異常的源代碼:
package org.springframework.security.crypto.bcrypt;
import java.security.SecureRandom;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
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;
}
}
}
public boolean matches()方法中進行判定密碼是否匹配。
二:解決方法:
修改密碼加密的方式:
一開始我的代碼:
User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),userInfo.getStatus()==0?false:true,true,true,true,getAuthority(userInfo.getRoles()));
改變成:
BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
// User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(), getAuthority(userInfo.getRoles()));
User user=new User(userInfo.getUsername(),"{noop}"+bCryptPasswordEncoder.encode(userInfo.getPassword()),userInfo.getStatus()==0?false:true,true,true,true,getAuthority(userInfo.getRoles()));
三:Spring Securit加密方式
BCrypt 算法與 MD5/SHA 算法有一個很大的區別,每次生成的 hash 值都是不同的,就可以免除存儲 salt,暴力破解起來也更困難。BCrypt 加密後的字符長度比較長,有60位,所以用戶表中密碼字段的長度,如果打算採用 BCrypt 加密存儲,字段長度不得低於 68(需要前綴 {bcrypt})。
對於Spring Security的學習,本博主後續會寫。