密码复杂度
This commit is contained in:
parent
acdd2d197d
commit
abb25643db
|
|
@ -50,6 +50,7 @@ import com.bonus.common.houqin.domain.SmsCodeVerifyDTO;
|
|||
import com.bonus.common.houqin.utils.AesEncryptUtil;
|
||||
import com.bonus.common.houqin.utils.LeBeanUtil;
|
||||
import com.bonus.common.houqin.utils.id.Id;
|
||||
import com.bonus.common.security.utils.SecurityUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -205,6 +206,10 @@ public class CustInfoServiceImpl extends ServiceImpl<CustInfoMapper, CustInfo> i
|
|||
content.setNewPassword(AesEncryptUtil.aesDecode(content.getNewPassword()));
|
||||
String oldPassword = content.getOldPassword();
|
||||
String newPassword = content.getNewPassword();
|
||||
AjaxResult pwdCheckResult = validatePassword(oldPassword, newPassword);
|
||||
if (ajaxResult.isError()) {
|
||||
return pwdCheckResult;
|
||||
}
|
||||
if (Objects.equals(oldPassword, newPassword)) {
|
||||
log.error("小程序修改密码错误:两次密码不能一致");
|
||||
ajaxResult.put("msg", "小程序修改密码错误:两次密码不能一致");
|
||||
|
|
@ -230,11 +235,192 @@ public class CustInfoServiceImpl extends ServiceImpl<CustInfoMapper, CustInfo> i
|
|||
return ajaxResult;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// BCryptPasswordEncoder bCrypt = new BCryptPasswordEncoder();
|
||||
// boolean flag = bCrypt.matches("Bonus$2026", "$2a$10$vrcmG0TyvgH5tS9g8ptaVOK2K3pYWVAa13SWEK7pQBGRtNAPlGV7O");
|
||||
// System.out.println(flag);
|
||||
// }
|
||||
public AjaxResult validatePassword(String oldPassword, String newPassword) {
|
||||
// 1. 检查密码长度
|
||||
if (!isPasswordLengthValid(newPassword)) {
|
||||
return AjaxResult.error("密码长度应为6至16位!");
|
||||
}
|
||||
|
||||
// 2. 检查密码字符类型
|
||||
if (!isPasswordCharacterValid(newPassword)) {
|
||||
return AjaxResult.error("密码不符合字符要求!");
|
||||
}
|
||||
|
||||
// 3. 检查常见弱密码
|
||||
if (containsWeakPassword(newPassword.toLowerCase())) {
|
||||
return AjaxResult.error("密码包含常见的弱密码片段!");
|
||||
}
|
||||
|
||||
// 4. 检查连续字符
|
||||
if (containsConsecutiveCharacters(newPassword.toLowerCase(), 3)) {
|
||||
return AjaxResult.error("密码不能包含超过3位连续字符!");
|
||||
}
|
||||
|
||||
// 5. 检查新旧密码是否相同
|
||||
if (SecurityUtils.matchesPassword(newPassword, oldPassword)) {
|
||||
return AjaxResult.error("新密码不能与原密码相同!");
|
||||
}
|
||||
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
private boolean isPasswordLengthValid(String password) {
|
||||
return password.length() >= 6 && password.length() <= 16;
|
||||
}
|
||||
|
||||
private boolean isPasswordCharacterValid(String password) {
|
||||
boolean hasUpperCase = false, hasLowerCase = false, hasDigit = false, hasSpecialChar = false;
|
||||
|
||||
for (char c : password.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
hasUpperCase = true;
|
||||
}
|
||||
if (Character.isLowerCase(c)) {
|
||||
hasLowerCase = true;
|
||||
}
|
||||
if (Character.isDigit(c)) {
|
||||
hasDigit = true;
|
||||
}
|
||||
if ("!@#$%^&*()-_=+[{]};:'\",<.>/?".indexOf(c) >= 0) {
|
||||
hasSpecialChar = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasUpperCase) {
|
||||
return false;
|
||||
}
|
||||
if (!hasLowerCase) {
|
||||
return false;
|
||||
}
|
||||
if (!hasDigit) {
|
||||
return false;
|
||||
}
|
||||
return !(true && !hasSpecialChar);
|
||||
}
|
||||
|
||||
private boolean containsWeakPassword(String password) {
|
||||
Set<String> weakPasswords = new HashSet<>(Arrays.asList("111",
|
||||
"888",
|
||||
"123",
|
||||
"234",
|
||||
"345",
|
||||
"456",
|
||||
"567",
|
||||
"678",
|
||||
"789",
|
||||
"1234",
|
||||
"2345",
|
||||
"3456",
|
||||
"4567",
|
||||
"5678",
|
||||
"6789",
|
||||
"abc",
|
||||
"abcd",
|
||||
"abcde",
|
||||
"abcdef",
|
||||
"abcdefg",
|
||||
"qwe",
|
||||
"qwer",
|
||||
"qwert",
|
||||
"qwerty",
|
||||
"asdf",
|
||||
"asdfg",
|
||||
"asdfgh",
|
||||
"password",
|
||||
"passw0rd",
|
||||
"letmein",
|
||||
"welcome",
|
||||
"admin",
|
||||
"user",
|
||||
"test",
|
||||
"pass",
|
||||
"root",
|
||||
"login"));
|
||||
for (String weakPwd : weakPasswords) {
|
||||
if (password.contains(weakPwd)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查密码中是否包含超过 n 个连续相同字符、连续递增/递减的数字或字母(不区分大小写)
|
||||
*/
|
||||
private boolean containsConsecutiveCharacters(String password, int n) {
|
||||
// 检查连续相同字符
|
||||
n = n + 1;
|
||||
for (int i = 0; i <= password.length() - n; i++) {
|
||||
boolean consecutiveSameChar = true;
|
||||
for (int j = 1; j < n; j++) {
|
||||
if (password.charAt(i + j) != password.charAt(i)) {
|
||||
consecutiveSameChar = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (consecutiveSameChar) {
|
||||
return true; // 包含超过 n 个连续相同字符
|
||||
}
|
||||
}
|
||||
|
||||
// 检查连续递增或递减的数字
|
||||
for (int i = 0; i <= password.length() - n; i++) {
|
||||
boolean consecutiveIncreasing = true;
|
||||
boolean consecutiveDecreasing = true;
|
||||
for (int j = 1; j < n; j++) {
|
||||
char currentChar = password.charAt(i);
|
||||
char nextChar = password.charAt(i + j);
|
||||
|
||||
// 检查数字递增或递减
|
||||
if (Character.isDigit(currentChar) && Character.isDigit(nextChar)) {
|
||||
if (nextChar != currentChar + j) {
|
||||
consecutiveIncreasing = false;
|
||||
}
|
||||
if (nextChar != currentChar - j) {
|
||||
consecutiveDecreasing = false;
|
||||
}
|
||||
} else {
|
||||
consecutiveIncreasing = false;
|
||||
consecutiveDecreasing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (consecutiveIncreasing || consecutiveDecreasing) {
|
||||
return true; // 包含超过 n 个递增或递减的连续数字
|
||||
}
|
||||
}
|
||||
|
||||
// 检查连续递增或递减的字母(不区分大小写)
|
||||
for (int i = 0; i <= password.length() - n; i++) {
|
||||
boolean consecutiveIncreasing = true;
|
||||
boolean consecutiveDecreasing = true;
|
||||
for (int j = 1; j < n; j++) {
|
||||
char currentChar = Character.toLowerCase(password.charAt(i)); // 转为小写
|
||||
char nextChar = Character.toLowerCase(password.charAt(i + j)); // 转为小写
|
||||
|
||||
// 检查字母递增或递减
|
||||
if (Character.isLetter(currentChar) && Character.isLetter(nextChar)) {
|
||||
if (nextChar != currentChar + j) {
|
||||
consecutiveIncreasing = false;
|
||||
}
|
||||
if (nextChar != currentChar - j) {
|
||||
consecutiveDecreasing = false;
|
||||
}
|
||||
} else {
|
||||
consecutiveIncreasing = false;
|
||||
consecutiveDecreasing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (consecutiveIncreasing || consecutiveDecreasing) {
|
||||
// 包含超过 n 个递增或递减的连续字母
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 不包含连续相同字符、数字或字母序列
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AjaxResult custForgetPassword(CustForgetPasswordDTO content) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue