From 3ea55f30f8d3bf043f85ab6c2a510ec5b69afb76 Mon Sep 17 00:00:00 2001 From: vincent Date: Wed, 30 Sep 2026 16:26:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=99=BB=E5=BD=95=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/EfcodeVirtualUnitServiceImpl.java | 16 +- .../config/PasswordPartyConfig.java | 19 -- .../controller/app/LoginController.java | 27 ++- .../enforcement/AppEnfLoginController.java | 2 +- .../supervision/AppSupLoginController.java | 2 +- .../service/CryptoSensitiveHsmService.java | 69 ------ .../impl/CryptoSensitiveHsmServiceImpl.java | 196 ------------------ .../service/thirdparty/PasswordPartyDemo.java | 1 - .../impl/PasswordPartyServiceImpl.java | 3 - zdxt-modules/zdxt-system/pom.xml | 4 + .../system/SysProfileController.java | 27 ++- .../controller/system/SysUserController.java | 21 +- 12 files changed, 88 insertions(+), 299 deletions(-) delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/config/PasswordPartyConfig.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/CryptoSensitiveHsmService.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveHsmServiceImpl.java diff --git a/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java b/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java index 1675b6ff..7c82cb5f 100644 --- a/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java @@ -1,6 +1,7 @@ package com.zdxt.enforcementcode.service.impl; import com.zdxt.enforcementcode.mapper.SrzDeptMapper; +import com.zdxt.enforcementcode.service.CryptoSensitiveHsmService; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.exception.ServiceException; @@ -16,6 +17,7 @@ import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.lang.tree.TreeNodeConfig; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zdxt.enforcementcode.domain.bo.EfcodeVirtualUnitBo; import com.zdxt.enforcementcode.domain.bo.UnitUserBo; @@ -56,6 +58,9 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { private final SysUserMapper sysUserMapper; private final ISysDeptService sysDeptService; + @Autowired + private CryptoSensitiveHsmService cryptoSensitiveHsmService; + /** * 查询虚拟单位树 * @@ -453,7 +458,6 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { if (user == null) { throw new ServiceException("用户不存在"); } - // salt 为空时生成新的 salt,保证与登录校验方式一致 String salt = user.getSalt(); LambdaUpdateWrapper uw = Wrappers.lambdaUpdate() .eq(SysUser::getUserId, userId); @@ -461,8 +465,16 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { salt = cn.hutool.core.util.RandomUtil.randomString("0123456789abcdef", 6); uw.set(SysUser::getSalt, salt); } - uw.set(SysUser::getPassword, DigestUtil.md5Hex(user.getLoginName() + password + salt)); + String md5Password = DigestUtil.md5Hex(user.getLoginName() + password + salt); + uw.set(SysUser::getPassword, md5Password); sysUserMapper.update(null, uw); + + try { + String bizId = String.valueOf(userId); + cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + } catch (Exception e) { + log.warn("HSM加密重置密码失败, userId={}", userId, e); + } } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/config/PasswordPartyConfig.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/config/PasswordPartyConfig.java deleted file mode 100644 index 630a55fb..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/config/PasswordPartyConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.zdxt.enforcementcode.config; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -@Component -@ConfigurationProperties(prefix = "password-party") -public class PasswordPartyConfig { - - private String baseUrl; - - public String getBaseUrl() { - return baseUrl; - } - - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; - } -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/LoginController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/LoginController.java index c37de1fd..16b8c73e 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/LoginController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/LoginController.java @@ -4,6 +4,8 @@ import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.parameter.SaLoginParameter; import cn.hutool.crypto.digest.DigestUtil; import com.zdxt.enforcementcode.common.commonenum.PlatformTypeEnums; +import com.zdxt.enforcementcode.common.config.RuoYiConfig; +import com.zdxt.enforcementcode.service.CryptoSensitiveHsmService; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.model.LoginUser; @@ -11,8 +13,6 @@ import org.dromara.common.encrypt.utils.EncryptUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.springframework.beans.factory.annotation.Autowired; -import java.nio.charset.StandardCharsets; -import java.util.Base64; import java.util.Map; /** @@ -39,7 +39,11 @@ public abstract class LoginController { protected static final long APP_TOKEN_ACTIVE_TIMEOUT = 86400; @Autowired - private com.zdxt.enforcementcode.common.config.RuoYiConfig ruoYiConfig; + private RuoYiConfig ruoYiConfig; + + @Autowired + private CryptoSensitiveHsmService cryptoSensitiveHsmService; + /** * 校验登录参数非空 @@ -78,6 +82,23 @@ public abstract class LoginController { return md5Password.equals(storedPassword); } + /** + * HSM优先的密码校验(App端登录使用) + * 优先从 crypto_sensitive_data 解密比对,降级使用 MD5+salt + */ + protected boolean verifyPasswordWithHsm(Long userId, String loginName, String decryptedPassword, String salt, String storedPassword) { + String bizId = String.valueOf(userId); + try { + if (cryptoSensitiveHsmService.verifyPassword("sys_user", bizId, decryptedPassword)) { + return true; + } + } catch (Exception e) { + log.warn("HSM密码校验失败, userId={}, 降级使用MD5校验", userId); + } + String md5Password = DigestUtil.md5Hex(loginName + decryptedPassword + salt); + return md5Password.equals(storedPassword); + } + /** * 构建LoginUser并执行SaToken登录 * diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java index 503bd549..fc159fca 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java @@ -89,7 +89,7 @@ public class AppEnfLoginController extends LoginController { } // 5. MD5加盐校验密码(使用loginName作为加盐因子) - if (!verifyPassword(loginName, decryptedPassword, user.getSalt(), user.getPassword())) { + if (!verifyPasswordWithHsm(user.getUserId(), loginName, decryptedPassword, user.getSalt(), user.getPassword())) { return R.fail("用户名或密码错误"); } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/supervision/AppSupLoginController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/supervision/AppSupLoginController.java index 3952a983..4d3e44f5 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/supervision/AppSupLoginController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/supervision/AppSupLoginController.java @@ -65,7 +65,7 @@ public class AppSupLoginController extends LoginController { } // 5. MD5加盐校验密码 - if (!verifyPassword(user.getUserName(), decryptedPassword, user.getSalt(), user.getPassword())) { + if (!verifyPasswordWithHsm(user.getUserId(), user.getUserName(), decryptedPassword, user.getSalt(), user.getPassword())) { return R.fail("用户名或密码错误"); } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/CryptoSensitiveHsmService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/CryptoSensitiveHsmService.java deleted file mode 100644 index 75c7d8f1..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/CryptoSensitiveHsmService.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.zdxt.enforcementcode.service; - -import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; - -/** - * 密评敏感字段 HSM 加密服务 - *

- * 通过 HSM 密码服务平台对敏感字段进行加密存储,满足密评合规要求。 - * 手机号/身份证号使用 SM4-CBC 对称加密,密码使用 HMAC-SM3 单向哈希。 - */ -public interface CryptoSensitiveHsmService { - - /** - * 加密并存储敏感字段(SM4-CBC 对称加密) - * - * @param tableName 业务表名,如 sys_user - * @param bizId 业务记录主键 - * @param fieldCode 字段编码,如 phone / id_card - * @param plainText 明文值 - * @return HSM 加密后的密文(cipherText),加密失败或明文为空时返回 null - */ - String encryptAndSave(String tableName, String bizId, String fieldCode, String plainText); - - /** - * 哈希并存储密码(HMAC-SM3 单向哈希) - *

- * 生成随机 salt,调用 HSM /hsm/api/HmacWithIndex 接口计算哈希, - * 哈希值存入 plain_hash,salt 存入 field_salt,cipher_text 为空。 - * - * @param tableName 业务表名 - * @param bizId 业务记录主键 - * @param plainPassword 明文密码 - * @return 生成的盐值(Hex),供登录校验时使用 - */ - String hashAndSavePassword(String tableName, String bizId, String plainPassword); - - /** - * 验证密码是否匹配 - * - * @param tableName 业务表名 - * @param bizId 业务记录主键 - * @param plainPassword 明文密码 - * @return true=匹配 - */ - boolean verifyPassword(String tableName, String bizId, String plainPassword); - - /** - * 解密获取明文(SM4-CBC 对称解密) - * - * @param tableName 业务表名 - * @param bizId 业务记录主键 - * @param fieldCode 字段编码 - * @return 明文值,不存在则返回 null - */ - String decryptField(String tableName, String bizId, String fieldCode); - - /** - * 计算并存储数据完整性摘要(HMAC-SM3) - *

- * 将多个业务字段明文拼接后,调用 HSM HMAC-SM3 计算摘要, - * 结果存入 crypto_integrity_data 表,用于后续完整性校验。 - * - * @param tableName 业务表名,如 sys_user - * @param bizId 业务记录主键 - * @param fieldList 参与摘要的字段列表,逗号分隔,如 password,phonenumber,certificateNumber - * @param plainValues 与 fieldList 顺序一致的明文值 - */ - void saveIntegrityHash(String tableName, String bizId, String fieldList, String... plainValues); -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveHsmServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveHsmServiceImpl.java deleted file mode 100644 index d8f66d3f..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveHsmServiceImpl.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.zdxt.enforcementcode.service.impl; - -import cn.hutool.core.util.HexUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.zdxt.enforcementcode.domain.bean.CryptoIntegrityData; -import com.zdxt.enforcementcode.domain.bean.CryptoOperationAudit; -import com.zdxt.enforcementcode.domain.bean.CryptoSensitiveData; -import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; -import com.zdxt.enforcementcode.mapper.CryptoIntegrityDataMapper; -import com.zdxt.enforcementcode.mapper.CryptoOperationAuditMapper; -import com.zdxt.enforcementcode.mapper.CryptoSensitiveDataMapper; -import com.zdxt.enforcementcode.service.CryptoSensitiveHsmService; -import com.zdxt.enforcementcode.service.thirdparty.IPasswordPartyService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.satoken.utils.LoginHelper; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.nio.charset.StandardCharsets; -import java.security.SecureRandom; -import java.util.Date; - -@Slf4j -@RequiredArgsConstructor -@Service -public class CryptoSensitiveHsmServiceImpl implements CryptoSensitiveHsmService { - - private final IPasswordPartyService passwordPartyService; - private final CryptoSensitiveDataMapper cryptoSensitiveDataMapper; - private final CryptoOperationAuditMapper cryptoOperationAuditMapper; - private final CryptoIntegrityDataMapper cryptoIntegrityDataMapper; - - private static final String KEY_VERSION = "V1"; - private static final String TABLE_SYS_USER = "sys_user"; - - @Override - @Transactional(rollbackFor = Exception.class) - public String encryptAndSave(String tableName, String bizId, String fieldCode, String plainText) { - if (StrUtil.isBlank(plainText)) { - return null; - } - String inputHex = HexUtil.encodeHexStr(plainText.getBytes(StandardCharsets.UTF_8)); - SymmetryEncryptVo encryptResult = passwordPartyService.symmetryEncrypt(inputHex); - - CryptoSensitiveData existing = queryActiveRecord(tableName, bizId, fieldCode); - if (existing != null) { - existing.setCipherText(encryptResult.getOutData()); - existing.setFieldIv(encryptResult.getIvData()); - existing.setFieldValue(plainText); - existing.setEncryptAlg("SM4-CBC"); - existing.setKeyVersion(KEY_VERSION); - cryptoSensitiveDataMapper.updateById(existing); - saveAuditRecord(tableName, bizId, fieldCode, existing.getId(), 3, "HSM SM4-CBC 加密更新"); - } else { - CryptoSensitiveData record = new CryptoSensitiveData(); - record.setTableName(tableName); - record.setBizId(bizId); - record.setFieldCode(fieldCode); - record.setFieldValue(plainText); - record.setCipherText(encryptResult.getOutData()); - record.setFieldIv(encryptResult.getIvData()); - record.setEncryptAlg("SM4-CBC"); - record.setKeyVersion(KEY_VERSION); - record.setIsActive(1); - record.setIsDeleted(0); - cryptoSensitiveDataMapper.insert(record); - saveAuditRecord(tableName, bizId, fieldCode, record.getId(), 1, "HSM SM4-CBC 加密存储"); - } - return encryptResult.getOutData(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public String hashAndSavePassword(String tableName, String bizId, String plainPassword) { - if (StrUtil.isBlank(plainPassword)) { - return null; - } - return encryptAndSave(tableName, bizId, "password", plainPassword); - } - - @Override - public boolean verifyPassword(String tableName, String bizId, String plainPassword) { - CryptoSensitiveData record = queryActiveRecord(tableName, bizId, "password"); - if (record == null || StrUtil.isBlank(record.getCipherText()) || StrUtil.isBlank(record.getFieldIv())) { - return false; - } - try { - SymmetryEncryptVo decryptResult = passwordPartyService.symmetryDecrypt(record.getFieldIv(), record.getCipherText()); - byte[] plainBytes = hexToBytes(decryptResult.getOutData()); - String decryptedPassword = new String(plainBytes, StandardCharsets.UTF_8); - return decryptedPassword.equals(plainPassword); - } catch (Exception e) { - log.error("HSM解密密码验证失败, tableName={}, bizId={}", tableName, bizId, e); - return false; - } - } - - @Override - public String decryptField(String tableName, String bizId, String fieldCode) { - CryptoSensitiveData record = queryActiveRecord(tableName, bizId, fieldCode); - if (record == null || StrUtil.isBlank(record.getCipherText())) { - return null; - } - SymmetryEncryptVo decryptResult = passwordPartyService.symmetryDecrypt(record.getFieldIv(), record.getCipherText()); - byte[] plainBytes = hexToBytes(decryptResult.getOutData()); - return new String(plainBytes, StandardCharsets.UTF_8); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void saveIntegrityHash(String tableName, String bizId, String fieldList, String... plainValues) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < plainValues.length; i++) { - if (i > 0) sb.append(","); - sb.append(plainValues[i] != null ? plainValues[i] : ""); - } - String concatPlain = sb.toString(); - String inputHex = HexUtil.encodeHexStr(concatPlain.getBytes(StandardCharsets.UTF_8)); - String hmacHash = passwordPartyService.hmacWithIndex(inputHex); - - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - lqw.eq(CryptoIntegrityData::getTableName, tableName) - .eq(CryptoIntegrityData::getBizId, bizId) - .eq(CryptoIntegrityData::getIsDeleted, 0); - CryptoIntegrityData existing = cryptoIntegrityDataMapper.selectOne(lqw); - - if (existing != null) { - existing.setFieldList(fieldList); - existing.setSm3Hash(hmacHash); - existing.setHashAlg("SM3"); - existing.setGenerateTime(new Date()); - existing.setVerifyResult(0); - cryptoIntegrityDataMapper.updateById(existing); - } else { - CryptoIntegrityData record = new CryptoIntegrityData(); - record.setTableName(tableName); - record.setBizId(bizId); - record.setFieldList(fieldList); - record.setSm3Hash(hmacHash); - record.setHashAlg("SM3"); - record.setGenerateTime(new Date()); - record.setVerifyResult(0); - record.setIsDeleted(0); - cryptoIntegrityDataMapper.insert(record); - } - } - - private CryptoSensitiveData queryActiveRecord(String tableName, String bizId, String fieldCode) { - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - lqw.eq(CryptoSensitiveData::getTableName, tableName) - .eq(CryptoSensitiveData::getBizId, bizId) - .eq(CryptoSensitiveData::getFieldCode, fieldCode) - .eq(CryptoSensitiveData::getIsActive, 1) - .eq(CryptoSensitiveData::getIsDeleted, 0); - return cryptoSensitiveDataMapper.selectOne(lqw); - } - - private void deactivateExisting(String tableName, String bizId, String fieldCode) { - LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>(); - uw.eq(CryptoSensitiveData::getTableName, tableName) - .eq(CryptoSensitiveData::getBizId, bizId) - .eq(CryptoSensitiveData::getFieldCode, fieldCode) - .eq(CryptoSensitiveData::getIsActive, 1) - .set(CryptoSensitiveData::getIsActive, 0); - cryptoSensitiveDataMapper.update(null, uw); - } - - private void saveAuditRecord(String tableName, String bizId, String fieldCode, - Long sensitiveDataId, int operateType, String remark) { - CryptoOperationAudit audit = new CryptoOperationAudit(); - audit.setSensitiveDataId(sensitiveDataId); - audit.setTableName(tableName); - audit.setBizId(bizId); - audit.setFieldCode(fieldCode); - audit.setOperateType(operateType); - audit.setRemark(remark); - try { - audit.setOperatorId(LoginHelper.getUserId()); - } catch (Exception ignored) { - } - cryptoOperationAuditMapper.insert(audit); - } - - private static byte[] hexToBytes(String hex) { - int len = hex.length(); - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) - + Character.digit(hex.charAt(i + 1), 16)); - } - return data; - } -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java index db56e322..e2c7523b 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java @@ -1,6 +1,5 @@ package com.zdxt.enforcementcode.service.thirdparty; -import com.zdxt.enforcementcode.config.PasswordPartyConfig; import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; import com.zdxt.enforcementcode.service.thirdparty.impl.PasswordPartyServiceImpl; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java index fa628197..420f2f25 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java @@ -3,7 +3,6 @@ package com.zdxt.enforcementcode.service.thirdparty.impl; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSONObject; -import com.zdxt.enforcementcode.config.PasswordPartyConfig; import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; import com.zdxt.enforcementcode.service.thirdparty.IPasswordPartyService; import lombok.RequiredArgsConstructor; @@ -11,8 +10,6 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.exception.base.BaseException; import org.springframework.stereotype.Service; -import java.security.SecureRandom; - /** * 密码服务平台 * diff --git a/zdxt-modules/zdxt-system/pom.xml b/zdxt-modules/zdxt-system/pom.xml index f7423637..c159f4b6 100644 --- a/zdxt-modules/zdxt-system/pom.xml +++ b/zdxt-modules/zdxt-system/pom.xml @@ -105,6 +105,10 @@ org.dromara zdxt-common-quartz + + org.dromara + zdxt-enforcement-code-common + diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java index cdf6b444..d26f3071 100644 --- a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java @@ -5,6 +5,7 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.digest.DigestUtil; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.file.MimeTypeUtils; @@ -23,6 +24,7 @@ import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.service.ISysOssService; import org.dromara.system.service.ISysUserService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -38,12 +40,16 @@ import java.util.Arrays; @Validated @RequiredArgsConstructor @RestController +@Slf4j @RequestMapping("/system/user/profile") public class SysProfileController extends BaseController { private final ISysUserService userService; private final ISysOssService ossService; + @Autowired + private com.zdxt.enforcementcode.service.CryptoSensitiveHsmService cryptoSensitiveHsmService; + /** * 个人信息 */ @@ -94,16 +100,33 @@ public class SysProfileController extends BaseController { SysUserVo user = userService.selectUserById(LoginHelper.getUserId()); String salt = user.getSalt(); String loginAccount = StringUtils.isNotBlank(user.getLoginName()) ? user.getLoginName() : user.getUserName(); - String oldEncrypted = DigestUtil.md5Hex(loginAccount + bo.getOldPassword() + salt); - if (!oldEncrypted.equals(user.getPassword())) { + + boolean oldPasswordCorrect = false; + String bizId = String.valueOf(user.getUserId()); + try { + oldPasswordCorrect = cryptoSensitiveHsmService.verifyPassword("sys_user", bizId, bo.getOldPassword()); + } catch (Exception e) { + log.warn("HSM校验旧密码失败, userId={}, 降级MD5校验", user.getUserId()); + } + if (!oldPasswordCorrect) { + String oldEncrypted = DigestUtil.md5Hex(loginAccount + bo.getOldPassword() + salt); + oldPasswordCorrect = oldEncrypted.equals(user.getPassword()); + } + if (!oldPasswordCorrect) { return R.fail("修改密码失败,旧密码错误"); } + String newEncrypted = DigestUtil.md5Hex(loginAccount + bo.getNewPassword() + salt); if (newEncrypted.equals(user.getPassword())) { return R.fail("新密码不能与旧密码相同"); } int rows = DataPermissionHelper.ignore(() -> userService.resetUserPwd(user.getUserId(), newEncrypted)); if (rows > 0) { + try { + cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", newEncrypted); + } catch (Exception e) { + log.warn("HSM加密新密码失败, userId={}", user.getUserId(), e); + } return R.ok(); } return R.fail("修改密码异常,请联系管理员"); diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysUserController.java index d0784cac..93a33fa1 100644 --- a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysUserController.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysUserController.java @@ -6,9 +6,11 @@ import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.crypto.digest.DigestUtil; +import com.zdxt.enforcementcode.service.CryptoSensitiveHsmService; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.model.LoginUser; @@ -33,6 +35,7 @@ import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.*; import org.dromara.system.listener.SysUserImportListener; import org.dromara.system.service.*; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -46,6 +49,8 @@ import java.util.List; * * @author Lion Li */ + +@Slf4j @Validated @RequiredArgsConstructor @RestController @@ -58,6 +63,9 @@ public class SysUserController extends BaseController { private final ISysDeptService deptService; private final ISysTenantService tenantService; + @Autowired + private CryptoSensitiveHsmService cryptoSensitiveHsmService; + /** * 获取用户列表 */ @@ -243,8 +251,17 @@ public class SysUserController extends BaseController { SysUserVo existingUser = userService.selectUserById(user.getUserId()); String salt = existingUser.getSalt(); String loginAccount = StringUtils.isNotBlank(existingUser.getLoginName()) ? existingUser.getLoginName() : existingUser.getUserName(); - user.setPassword(DigestUtil.md5Hex(loginAccount + user.getPassword() + salt)); - return toAjax(userService.resetUserPwd(user.getUserId(), user.getPassword())); + String md5Password = DigestUtil.md5Hex(loginAccount + user.getPassword() + salt); + int rows = userService.resetUserPwd(user.getUserId(), md5Password); + if (rows > 0) { + try { + String bizId = String.valueOf(user.getUserId()); + cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + } catch (Exception e) { + log.warn("HSM加密重置密码失败, userId={}", user.getUserId(), e); + } + } + return toAjax(rows); } /**