密码复杂度

This commit is contained in:
sxu 2025-04-25 13:42:48 +08:00
parent acdd2d197d
commit abb25643db
1 changed files with 191 additions and 5 deletions

View File

@ -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) {