From 004bbbabff0406b04bf071c8428643e0040001d9 Mon Sep 17 00:00:00 2001 From: vincent Date: Wed, 30 Sep 2026 17:32:38 +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 | 87 +++++++- .../controller/app/LoginController.java | 6 +- .../domain/bo/CryptoIntegrityDataBo.java | 78 ------- .../domain/bo/CryptoOperationAuditBo.java | 83 -------- .../domain/bo/CryptoSensitiveDataBo.java | 92 --------- .../quartz/job/SynUserInfoJob.java | 12 +- .../service/ICryptoIntegrityDataService.java | 24 --- .../service/ICryptoOperationAuditService.java | 24 --- .../service/ICryptoSensitiveDataService.java | 24 --- .../impl/CryptoIntegrityDataServiceImpl.java | 89 -------- .../impl/CryptoOperationAuditServiceImpl.java | 91 -------- .../impl/CryptoSensitiveDataServiceImpl.java | 91 -------- .../service/thirdparty/PasswordPartyDemo.java | 166 --------------- zdxt-modules/zdxt-system/pom.xml | 5 +- .../system/config/PasswordPartyConfig.java | 19 ++ .../system/SysProfileController.java | 17 +- .../controller/system/SysUserController.java | 17 +- .../domain/bean/CryptoIntegrityData.java | 7 +- .../domain/bean/CryptoOperationAudit.java | 7 +- .../domain/bean/CryptoSensitiveData.java | 7 +- .../domain/vo/CryptoIntegrityDataVo.java | 4 +- .../domain/vo/CryptoOperationAuditVo.java | 5 +- .../domain/vo/CryptoSensitiveDataVo.java | 4 +- .../system/domain/vo}/SymmetryEncryptVo.java | 2 +- .../dromara/system/domain/vo/SysUserVo.java | 3 + .../mapper/CryptoIntegrityDataMapper.java | 7 +- .../mapper/CryptoOperationAuditMapper.java | 6 +- .../mapper/CryptoSensitiveDataMapper.java | 7 +- .../service/ICryptoSensitiveHsmService.java | 67 ++++++ .../service}/IPasswordPartyService.java | 7 +- .../impl/CryptoSensitiveHsmServiceImpl.java | 195 ++++++++++++++++++ .../impl/PasswordPartyServiceImpl.java | 7 +- .../service/impl/PasswordAuthStrategy.java | 5 +- 33 files changed, 438 insertions(+), 827 deletions(-) delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoIntegrityDataBo.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoOperationAuditBo.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoSensitiveDataBo.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoIntegrityDataService.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoOperationAuditService.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoSensitiveDataService.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoIntegrityDataServiceImpl.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoOperationAuditServiceImpl.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveDataServiceImpl.java delete mode 100644 zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java create mode 100644 zdxt-modules/zdxt-system/src/main/java/org/dromara/system/config/PasswordPartyConfig.java rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/domain/bean/CryptoIntegrityData.java (87%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/domain/bean/CryptoOperationAudit.java (86%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/domain/bean/CryptoSensitiveData.java (89%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/domain/vo/CryptoIntegrityDataVo.java (93%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/domain/vo/CryptoOperationAuditVo.java (92%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/domain/vo/CryptoSensitiveDataVo.java (94%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/passwordparty => zdxt-system/src/main/java/org/dromara/system/domain/vo}/SymmetryEncryptVo.java (81%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/mapper/CryptoIntegrityDataMapper.java (50%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/mapper/CryptoOperationAuditMapper.java (51%) rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode => zdxt-system/src/main/java/org/dromara/system}/mapper/CryptoSensitiveDataMapper.java (51%) create mode 100644 zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ICryptoSensitiveHsmService.java rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty => zdxt-system/src/main/java/org/dromara/system/service}/IPasswordPartyService.java (91%) create mode 100644 zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/CryptoSensitiveHsmServiceImpl.java rename zdxt-modules/{zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty => zdxt-system/src/main/java/org/dromara/system/service}/impl/PasswordPartyServiceImpl.java (97%) 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 7c82cb5f..c4f7ac09 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,7 +1,6 @@ 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; @@ -17,6 +16,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.dromara.system.service.ICryptoSensitiveHsmService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zdxt.enforcementcode.domain.bo.EfcodeVirtualUnitBo; @@ -59,7 +59,7 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { private final ISysDeptService sysDeptService; @Autowired - private CryptoSensitiveHsmService cryptoSensitiveHsmService; + private ICryptoSensitiveHsmService ICryptoSensitiveHsmService; /** * 查询虚拟单位树 @@ -372,7 +372,6 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { */ @Override public void addUser(UnitUserBo bo) { - // 校验登录账号唯一性 long count = sysUserMapper.selectCount( Wrappers.lambdaQuery().eq(SysUser::getLoginName, bo.getLoginName()) ); @@ -390,13 +389,28 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { user.setNickName(bo.getFullname()); user.setOrganizationId(bo.getDeptId()); user.setMobileNumber(null); - // 生成6位十六进制salt并使用 MD5(loginName + password + salt) 加密 String salt = cn.hutool.core.util.RandomUtil.randomString("0123456789abcdef", 6); user.setSalt(salt); - user.setPassword(DigestUtil.md5Hex(bo.getLoginName() + bo.getPassword() + salt)); + String md5Password = DigestUtil.md5Hex(bo.getLoginName() + bo.getPassword() + salt); + user.setPassword(md5Password); user.setStatus(bo.getStatus() != null ? bo.getStatus() : "0"); user.setUserSource(10); sysUserMapper.insert(user); + + try { + String bizId = String.valueOf(user.getUserId()); + String passwordCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + if (StringUtils.isNotBlank(passwordCipher)) { + sysUserMapper.update(null, Wrappers.lambdaUpdate() + .eq(SysUser::getUserId, user.getUserId()) + .set(SysUser::getPassword, passwordCipher)); + } + ICryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, + "password,phonenumber,certificateNumber", + passwordCipher != null ? passwordCipher : md5Password, "", ""); + } catch (Exception e) { + log.warn("HSM加密新增用户密码失败, userId={}", user.getUserId(), e); + } } /** @@ -414,7 +428,6 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { if (user.getUserSource() == null || user.getUserSource() != 10) { throw new ServiceException("仅允许编辑本系统新增的用户"); } - // 若修改了登录账号,校验唯一性 if (StringUtils.isNotBlank(bo.getLoginName()) && !bo.getLoginName().equals(user.getLoginName())) { long count = sysUserMapper.selectCount( Wrappers.lambdaQuery().eq(SysUser::getLoginName, bo.getLoginName()) @@ -423,6 +436,10 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { throw new ServiceException("登录账号'" + bo.getLoginName() + "'已存在"); } } + + String md5Password = null; + String phoneCipher = null; + LambdaUpdateWrapper uw = Wrappers.lambdaUpdate() .eq(SysUser::getUserId, bo.getUserId()) .set(StringUtils.isNotBlank(bo.getDeptId()), SysUser::getDeptId, bo.getDeptId()) @@ -430,14 +447,50 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { .set(StringUtils.isNotBlank(bo.getFullname()), SysUser::getNickName, bo.getFullname()) .set(StringUtils.isNotBlank(bo.getLoginName()), SysUser::getLoginName, bo.getLoginName()) .set(StringUtils.isNotBlank(bo.getLoginName()), SysUser::getUserName, bo.getLoginName()) - .set(bo.getMobileNumber() != null, SysUser::getMobileNumber, bo.getMobileNumber()) .set(StringUtils.isNotBlank(bo.getStatus()), SysUser::getStatus, bo.getStatus()); + if (StringUtils.isNotBlank(bo.getPassword())) { String salt = user.getSalt(); String loginName = StringUtils.isNotBlank(bo.getLoginName()) ? bo.getLoginName() : user.getLoginName(); - uw.set(SysUser::getPassword, DigestUtil.md5Hex(loginName + bo.getPassword() + salt)); + md5Password = DigestUtil.md5Hex(loginName + bo.getPassword() + salt); + uw.set(SysUser::getPassword, md5Password); + } + + if (bo.getMobileNumber() != null) { + try { + String bizId = String.valueOf(bo.getUserId()); + phoneCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "phonenumber", bo.getMobileNumber()); + } catch (Exception e) { + log.warn("HSM加密手机号失败, userId={}", bo.getUserId(), e); + } + if (StringUtils.isNotBlank(phoneCipher)) { + uw.set(SysUser::getMobileNumber, phoneCipher); + } else { + uw.set(SysUser::getMobileNumber, bo.getMobileNumber()); + } } + sysUserMapper.update(null, uw); + + try { + String bizId = String.valueOf(bo.getUserId()); + if (StringUtils.isNotBlank(bo.getPassword()) && md5Password != null) { + String passwordCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + if (StringUtils.isNotBlank(passwordCipher)) { + sysUserMapper.update(null, Wrappers.lambdaUpdate() + .eq(SysUser::getUserId, bo.getUserId()) + .set(SysUser::getPassword, passwordCipher)); + } + } + SysUser updatedUser = sysUserMapper.selectById(bo.getUserId()); + ICryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, + "password,phonenumber,certificateNumber", + updatedUser.getPassword() != null ? updatedUser.getPassword() : "", + phoneCipher != null ? phoneCipher : (updatedUser.getPhonenumber() != null ? updatedUser.getPhonenumber() : ""), + updatedUser.getCertificateNumber() != null ? updatedUser.getCertificateNumber() : ""); + } catch (Exception e) { + log.warn("HSM完整性摘要更新失败, userId={}", bo.getUserId(), e); + } } /** @@ -471,10 +524,26 @@ public class EfcodeVirtualUnitServiceImpl implements IEfcodeVirtualUnitService { try { String bizId = String.valueOf(userId); - cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + String passwordCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + if (StringUtils.isNotBlank(passwordCipher)) { + sysUserMapper.update(null, Wrappers.lambdaUpdate() + .eq(SysUser::getUserId, userId) + .set(SysUser::getPassword, passwordCipher)); + } } catch (Exception e) { log.warn("HSM加密重置密码失败, userId={}", userId, e); } + try { + String bizId = String.valueOf(userId); + SysUser updatedUser = sysUserMapper.selectById(userId); + ICryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, + "password,phonenumber,certificateNumber", + updatedUser.getPassword() != null ? updatedUser.getPassword() : "", + updatedUser.getPhonenumber() != null ? updatedUser.getPhonenumber() : "", + updatedUser.getCertificateNumber() != null ? updatedUser.getCertificateNumber() : ""); + } catch (Exception e) { + log.warn("HSM完整性摘要更新失败, userId={}", userId, e); + } } 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 16b8c73e..4baacb8b 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 @@ -5,12 +5,12 @@ 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; import org.dromara.common.encrypt.utils.EncryptUtils; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.system.service.ICryptoSensitiveHsmService; import org.springframework.beans.factory.annotation.Autowired; import java.util.Map; @@ -42,7 +42,7 @@ public abstract class LoginController { private RuoYiConfig ruoYiConfig; @Autowired - private CryptoSensitiveHsmService cryptoSensitiveHsmService; + private ICryptoSensitiveHsmService ICryptoSensitiveHsmService; /** @@ -89,7 +89,7 @@ public abstract class LoginController { 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)) { + if (ICryptoSensitiveHsmService.verifyPassword("sys_user", bizId, decryptedPassword)) { return true; } } catch (Exception e) { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoIntegrityDataBo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoIntegrityDataBo.java deleted file mode 100644 index 7552a3e7..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoIntegrityDataBo.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.zdxt.enforcementcode.domain.bo; - -import com.zdxt.enforcementcode.domain.bean.CryptoIntegrityData; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import org.dromara.common.core.validate.AddGroup; -import org.dromara.common.core.validate.EditGroup; -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.*; -import java.util.Date; - -/** - * 数据完整性校验业务对象 crypto_integrity_data - * - * @author vincent - * @date 2026-09-28 - */ -@Data -@EqualsAndHashCode(callSuper = true) -@AutoMapper(target = CryptoIntegrityData.class, reverseConvertGenerate = false) -public class CryptoIntegrityDataBo extends BaseEntity { - - /** - * 主键ID - */ - @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) - private Long id; - - /** - * 业务表名,如 sys_user - */ - @NotBlank(message = "业务表名不能为空", groups = { AddGroup.class, EditGroup.class }) - private String tableName; - - /** - * 业务记录主键,字符串兼容数字/UUID - */ - @NotBlank(message = "业务记录主键不能为空", groups = { AddGroup.class, EditGroup.class }) - private String bizId; - - /** - * 参与完整性摘要的字段列表,逗号分隔:username,id_card,phone - */ - @NotBlank(message = "参与完整性摘要的字段列表不能为空", groups = { AddGroup.class, EditGroup.class }) - private String fieldList; - - /** - * 业务字段拼接明文的SM3摘要值,用于完整性校验 - */ - @NotBlank(message = "SM3摘要值不能为空", groups = { AddGroup.class, EditGroup.class }) - private String sm3Hash; - - /** - * 完整性哈希算法:SM3 - */ - private String hashAlg; - - /** - * 摘要生成时间 - */ - private Date generateTime; - - /** - * 最近一次完整性校验时间 - */ - private Date lastVerifyTime; - - /** - * 校验结果:0未校验 1校验通过 2校验失败(篡改) - */ - private Integer verifyResult; - - /** - * 逻辑删除 - */ - private Integer isDeleted; -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoOperationAuditBo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoOperationAuditBo.java deleted file mode 100644 index d3af3f78..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoOperationAuditBo.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.zdxt.enforcementcode.domain.bo; - -import com.zdxt.enforcementcode.domain.bean.CryptoOperationAudit; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import org.dromara.common.core.validate.AddGroup; -import org.dromara.common.core.validate.EditGroup; -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.*; -import java.util.Date; - -/** - * 密评敏感字段操作审计业务对象 crypto_operation_audit - * - * @author vincent - * @date 2026-09-28 - */ -@Data -@EqualsAndHashCode(callSuper = true) -@AutoMapper(target = CryptoOperationAudit.class, reverseConvertGenerate = false) -public class CryptoOperationAuditBo extends BaseEntity { - - /** - * 主键ID - */ - @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) - private Long id; - - /** - * 关联 crypto_sensitive_data 主键ID - */ - private Long sensitiveDataId; - - /** - * 业务表名 - */ - @NotBlank(message = "业务表名不能为空", groups = { AddGroup.class, EditGroup.class }) - private String tableName; - - /** - * 业务记录主键 - */ - @NotBlank(message = "业务记录主键不能为空", groups = { AddGroup.class, EditGroup.class }) - private String bizId; - - /** - * 敏感字段编码 - */ - @NotBlank(message = "敏感字段编码不能为空", groups = { AddGroup.class, EditGroup.class }) - private String fieldCode; - - /** - * 操作类型:1新增密文 2解密查看 3修改密文 4密钥轮换 - */ - @NotNull(message = "操作类型不能为空", groups = { AddGroup.class, EditGroup.class }) - private Integer operateType; - - /** - * 操作人ID(系统用户ID) - */ - private Long operatorId; - - /** - * 操作客户端IP地址 - */ - private String operatorIp; - - /** - * 操作发生时间 - */ - private Date operateTime; - - /** - * 操作备注信息 - */ - private String remark; - - /** - * 逻辑删除 - */ - private Integer isDeleted; -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoSensitiveDataBo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoSensitiveDataBo.java deleted file mode 100644 index f95caf4c..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoSensitiveDataBo.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.zdxt.enforcementcode.domain.bo; - -import com.zdxt.enforcementcode.domain.bean.CryptoSensitiveData; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import org.dromara.common.core.validate.AddGroup; -import org.dromara.common.core.validate.EditGroup; -import io.github.linpeilie.annotations.AutoMapper; -import lombok.Data; -import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.*; - -/** - * 密评敏感字段密文存储业务对象 crypto_sensitive_data - * - * @author vincent - * @date 2026-09-28 - */ -@Data -@EqualsAndHashCode(callSuper = true) -@AutoMapper(target = CryptoSensitiveData.class, reverseConvertGenerate = false) -public class CryptoSensitiveDataBo extends BaseEntity { - - /** - * 主键ID - */ - @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) - private Long id; - - /** - * 业务表名,如 sys_user - */ - @NotBlank(message = "业务表名不能为空", groups = { AddGroup.class, EditGroup.class }) - private String tableName; - - /** - * 业务表主键ID,字符串兼容数字/UUID主键 - */ - @NotBlank(message = "业务表主键ID不能为空", groups = { AddGroup.class, EditGroup.class }) - private String bizId; - - /** - * 业务字段编码,username/id_card/phone/password - */ - @NotBlank(message = "业务字段编码不能为空", groups = { AddGroup.class, EditGroup.class }) - private String fieldCode; - - /** - * 字段原始值 - */ - private String fieldValue; - - /** - * SM4-CBC密文Base64;password单向哈希场景此字段为空 - */ - private String cipherText; - - /** - * SM4-CBC初始化向量,16字节随机值Base64;password此字段为空 - */ - private String fieldIv; - - /** - * 明文SM3哈希,仅用于等值查询,不可逆 - */ - private String plainHash; - - /** - * 哈希盐值,仅password单向哈希字段使用 - */ - private String fieldSalt; - - /** - * 加密算法:SM4-CBC / SM3 - */ - private String encryptAlg; - - /** - * 密钥版本号,用于密钥轮换,密评必查 - */ - @NotBlank(message = "密钥版本号不能为空", groups = { AddGroup.class, EditGroup.class }) - private String keyVersion; - - /** - * 是否为当前有效密文:1有效,0历史旧密文(密钥轮换保留) - */ - private Integer isActive; - - /** - * 逻辑删除:0未删除,1已删除 - */ - private Integer isDeleted; -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/quartz/job/SynUserInfoJob.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/quartz/job/SynUserInfoJob.java index 284cb9fb..688149b0 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/quartz/job/SynUserInfoJob.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/quartz/job/SynUserInfoJob.java @@ -5,13 +5,13 @@ import cn.hutool.crypto.digest.DigestUtil; import com.zdxt.enforcementcode.common.util.IdCardCryptoUtil; import com.zdxt.enforcementcode.domain.bo.SrzUserBo; import com.zdxt.enforcementcode.domain.vo.SrzUserVo; -import com.zdxt.enforcementcode.service.CryptoSensitiveHsmService; import com.zdxt.enforcementcode.service.ISrzUserService; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.helper.DataPermissionHelper; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ICryptoSensitiveHsmService; import org.dromara.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -36,7 +36,7 @@ public class SynUserInfoJob { private ISysUserService sysUserService; @Autowired - private CryptoSensitiveHsmService cryptoSensitiveHsmService; + private ICryptoSensitiveHsmService ICryptoSensitiveHsmService; public void run() { this.userInfo(); @@ -140,14 +140,14 @@ public class SynUserInfoJob { // 密评规则:HSM 加密敏感字段存入 crypto_sensitive_data 表 String bizId = String.valueOf(userId); try { - String phoneCipher = cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "phonenumber", mobileNumber); - String idCardCipher = cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "certificateNumber", certificateNumber); + String phoneCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "phonenumber", mobileNumber); + String idCardCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "certificateNumber", certificateNumber); // 密码:仅新用户进行 HSM 加密,已有用户密码不动 String passwordCipher = null; SysUserBo updateBo = new SysUserBo(); updateBo.setUserId(userId); if (isNewUser) { - passwordCipher = cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", sysUserBo.getPassword()); + passwordCipher = ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", sysUserBo.getPassword()); updateBo.setPassword(passwordCipher); } updateBo.setPhonenumber(phoneCipher); @@ -164,7 +164,7 @@ public class SynUserInfoJob { } String phoneForHash = StringUtils.isNotEmpty(phoneCipher) ? phoneCipher : mobileNumber; String idCardForHash = StringUtils.isNotEmpty(idCardCipher) ? idCardCipher : certificateNumber; - cryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, + ICryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, "password,phonenumber,certificateNumber", pwdForHash, phoneForHash, idCardForHash); } catch (Exception e) { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoIntegrityDataService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoIntegrityDataService.java deleted file mode 100644 index c351734a..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoIntegrityDataService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.zdxt.enforcementcode.service; - -import com.zdxt.enforcementcode.domain.vo.CryptoIntegrityDataVo; -import com.zdxt.enforcementcode.domain.bo.CryptoIntegrityDataBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; - -import java.util.Collection; -import java.util.List; - -public interface ICryptoIntegrityDataService { - - CryptoIntegrityDataVo queryById(Long id); - - TableDataInfo queryPageList(CryptoIntegrityDataBo bo, PageQuery pageQuery); - - List queryList(CryptoIntegrityDataBo bo); - - Boolean insertByBo(CryptoIntegrityDataBo bo); - - Boolean updateByBo(CryptoIntegrityDataBo bo); - - Boolean deleteWithValidByIds(Collection ids, Boolean isValid); -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoOperationAuditService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoOperationAuditService.java deleted file mode 100644 index c4eacfa3..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoOperationAuditService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.zdxt.enforcementcode.service; - -import com.zdxt.enforcementcode.domain.vo.CryptoOperationAuditVo; -import com.zdxt.enforcementcode.domain.bo.CryptoOperationAuditBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; - -import java.util.Collection; -import java.util.List; - -public interface ICryptoOperationAuditService { - - CryptoOperationAuditVo queryById(Long id); - - TableDataInfo queryPageList(CryptoOperationAuditBo bo, PageQuery pageQuery); - - List queryList(CryptoOperationAuditBo bo); - - Boolean insertByBo(CryptoOperationAuditBo bo); - - Boolean updateByBo(CryptoOperationAuditBo bo); - - Boolean deleteWithValidByIds(Collection ids, Boolean isValid); -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoSensitiveDataService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoSensitiveDataService.java deleted file mode 100644 index 1eb3f7da..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoSensitiveDataService.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.zdxt.enforcementcode.service; - -import com.zdxt.enforcementcode.domain.vo.CryptoSensitiveDataVo; -import com.zdxt.enforcementcode.domain.bo.CryptoSensitiveDataBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; - -import java.util.Collection; -import java.util.List; - -public interface ICryptoSensitiveDataService { - - CryptoSensitiveDataVo queryById(Long id); - - TableDataInfo queryPageList(CryptoSensitiveDataBo bo, PageQuery pageQuery); - - List queryList(CryptoSensitiveDataBo bo); - - Boolean insertByBo(CryptoSensitiveDataBo bo); - - Boolean updateByBo(CryptoSensitiveDataBo bo); - - Boolean deleteWithValidByIds(Collection ids, Boolean isValid); -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoIntegrityDataServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoIntegrityDataServiceImpl.java deleted file mode 100644 index 073fb62f..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoIntegrityDataServiceImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.zdxt.enforcementcode.service.impl; - -import com.zdxt.enforcementcode.domain.bean.CryptoIntegrityData; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import com.zdxt.enforcementcode.domain.bo.CryptoIntegrityDataBo; -import com.zdxt.enforcementcode.domain.vo.CryptoIntegrityDataVo; -import com.zdxt.enforcementcode.mapper.CryptoIntegrityDataMapper; -import com.zdxt.enforcementcode.service.ICryptoIntegrityDataService; - -import java.util.List; -import java.util.Map; -import java.util.Collection; - -@Slf4j -@RequiredArgsConstructor -@Service -public class CryptoIntegrityDataServiceImpl implements ICryptoIntegrityDataService { - - private final CryptoIntegrityDataMapper baseMapper; - - @Override - public CryptoIntegrityDataVo queryById(Long id) { - return baseMapper.selectVoById(id); - } - - @Override - public TableDataInfo queryPageList(CryptoIntegrityDataBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - @Override - public List queryList(CryptoIntegrityDataBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(CryptoIntegrityDataBo bo) { - Map params = bo.getParams(); - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(CryptoIntegrityData::getId); - lqw.eq(StringUtils.isNotBlank(bo.getTableName()), CryptoIntegrityData::getTableName, bo.getTableName()); - lqw.eq(StringUtils.isNotBlank(bo.getBizId()), CryptoIntegrityData::getBizId, bo.getBizId()); - lqw.eq(StringUtils.isNotBlank(bo.getHashAlg()), CryptoIntegrityData::getHashAlg, bo.getHashAlg()); - lqw.eq(bo.getVerifyResult() != null, CryptoIntegrityData::getVerifyResult, bo.getVerifyResult()); - lqw.eq(bo.getIsDeleted() != null, CryptoIntegrityData::getIsDeleted, bo.getIsDeleted()); - return lqw; - } - - @Override - public Boolean insertByBo(CryptoIntegrityDataBo bo) { - CryptoIntegrityData add = MapstructUtils.convert(bo, CryptoIntegrityData.class); - validEntityBeforeSave(add); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setId(add.getId()); - } - return flag; - } - - @Override - public Boolean updateByBo(CryptoIntegrityDataBo bo) { - CryptoIntegrityData update = MapstructUtils.convert(bo, CryptoIntegrityData.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - private void validEntityBeforeSave(CryptoIntegrityData entity) { - //TODO 做一些数据校验,如唯一约束 - } - - @Override - public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 - } - return baseMapper.deleteByIds(ids) > 0; - } -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoOperationAuditServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoOperationAuditServiceImpl.java deleted file mode 100644 index 470bc17b..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoOperationAuditServiceImpl.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.zdxt.enforcementcode.service.impl; - -import com.zdxt.enforcementcode.domain.bean.CryptoOperationAudit; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import com.zdxt.enforcementcode.domain.bo.CryptoOperationAuditBo; -import com.zdxt.enforcementcode.domain.vo.CryptoOperationAuditVo; -import com.zdxt.enforcementcode.mapper.CryptoOperationAuditMapper; -import com.zdxt.enforcementcode.service.ICryptoOperationAuditService; - -import java.util.List; -import java.util.Map; -import java.util.Collection; - -@Slf4j -@RequiredArgsConstructor -@Service -public class CryptoOperationAuditServiceImpl implements ICryptoOperationAuditService { - - private final CryptoOperationAuditMapper baseMapper; - - @Override - public CryptoOperationAuditVo queryById(Long id) { - return baseMapper.selectVoById(id); - } - - @Override - public TableDataInfo queryPageList(CryptoOperationAuditBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - @Override - public List queryList(CryptoOperationAuditBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(CryptoOperationAuditBo bo) { - Map params = bo.getParams(); - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(CryptoOperationAudit::getId); - lqw.eq(bo.getSensitiveDataId() != null, CryptoOperationAudit::getSensitiveDataId, bo.getSensitiveDataId()); - lqw.eq(StringUtils.isNotBlank(bo.getTableName()), CryptoOperationAudit::getTableName, bo.getTableName()); - lqw.eq(StringUtils.isNotBlank(bo.getBizId()), CryptoOperationAudit::getBizId, bo.getBizId()); - lqw.eq(StringUtils.isNotBlank(bo.getFieldCode()), CryptoOperationAudit::getFieldCode, bo.getFieldCode()); - lqw.eq(bo.getOperateType() != null, CryptoOperationAudit::getOperateType, bo.getOperateType()); - lqw.eq(bo.getOperatorId() != null, CryptoOperationAudit::getOperatorId, bo.getOperatorId()); - lqw.eq(bo.getIsDeleted() != null, CryptoOperationAudit::getIsDeleted, bo.getIsDeleted()); - return lqw; - } - - @Override - public Boolean insertByBo(CryptoOperationAuditBo bo) { - CryptoOperationAudit add = MapstructUtils.convert(bo, CryptoOperationAudit.class); - validEntityBeforeSave(add); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setId(add.getId()); - } - return flag; - } - - @Override - public Boolean updateByBo(CryptoOperationAuditBo bo) { - CryptoOperationAudit update = MapstructUtils.convert(bo, CryptoOperationAudit.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - private void validEntityBeforeSave(CryptoOperationAudit entity) { - //TODO 做一些数据校验,如唯一约束 - } - - @Override - public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 - } - return baseMapper.deleteByIds(ids) > 0; - } -} diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveDataServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveDataServiceImpl.java deleted file mode 100644 index 71339339..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveDataServiceImpl.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.zdxt.enforcementcode.service.impl; - -import com.zdxt.enforcementcode.domain.bean.CryptoSensitiveData; -import org.dromara.common.core.utils.MapstructUtils; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.common.mybatis.core.page.TableDataInfo; -import org.dromara.common.mybatis.core.page.PageQuery; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import com.zdxt.enforcementcode.domain.bo.CryptoSensitiveDataBo; -import com.zdxt.enforcementcode.domain.vo.CryptoSensitiveDataVo; -import com.zdxt.enforcementcode.mapper.CryptoSensitiveDataMapper; -import com.zdxt.enforcementcode.service.ICryptoSensitiveDataService; - -import java.util.List; -import java.util.Map; -import java.util.Collection; - -@Slf4j -@RequiredArgsConstructor -@Service -public class CryptoSensitiveDataServiceImpl implements ICryptoSensitiveDataService { - - private final CryptoSensitiveDataMapper baseMapper; - - @Override - public CryptoSensitiveDataVo queryById(Long id) { - return baseMapper.selectVoById(id); - } - - @Override - public TableDataInfo queryPageList(CryptoSensitiveDataBo bo, PageQuery pageQuery) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); - return TableDataInfo.build(result); - } - - @Override - public List queryList(CryptoSensitiveDataBo bo) { - LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); - } - - private LambdaQueryWrapper buildQueryWrapper(CryptoSensitiveDataBo bo) { - Map params = bo.getParams(); - LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(CryptoSensitiveData::getId); - lqw.eq(StringUtils.isNotBlank(bo.getTableName()), CryptoSensitiveData::getTableName, bo.getTableName()); - lqw.eq(StringUtils.isNotBlank(bo.getBizId()), CryptoSensitiveData::getBizId, bo.getBizId()); - lqw.eq(StringUtils.isNotBlank(bo.getFieldCode()), CryptoSensitiveData::getFieldCode, bo.getFieldCode()); - lqw.eq(StringUtils.isNotBlank(bo.getEncryptAlg()), CryptoSensitiveData::getEncryptAlg, bo.getEncryptAlg()); - lqw.eq(StringUtils.isNotBlank(bo.getKeyVersion()), CryptoSensitiveData::getKeyVersion, bo.getKeyVersion()); - lqw.eq(bo.getIsActive() != null, CryptoSensitiveData::getIsActive, bo.getIsActive()); - lqw.eq(bo.getIsDeleted() != null, CryptoSensitiveData::getIsDeleted, bo.getIsDeleted()); - return lqw; - } - - @Override - public Boolean insertByBo(CryptoSensitiveDataBo bo) { - CryptoSensitiveData add = MapstructUtils.convert(bo, CryptoSensitiveData.class); - validEntityBeforeSave(add); - boolean flag = baseMapper.insert(add) > 0; - if (flag) { - bo.setId(add.getId()); - } - return flag; - } - - @Override - public Boolean updateByBo(CryptoSensitiveDataBo bo) { - CryptoSensitiveData update = MapstructUtils.convert(bo, CryptoSensitiveData.class); - validEntityBeforeSave(update); - return baseMapper.updateById(update) > 0; - } - - private void validEntityBeforeSave(CryptoSensitiveData entity) { - //TODO 做一些数据校验,如唯一约束 - } - - @Override - public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { - if (isValid) { - //TODO 做一些业务上的校验,判断是否需要校验 - } - return baseMapper.deleteByIds(ids) > 0; - } -} 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 deleted file mode 100644 index e2c7523b..00000000 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.zdxt.enforcementcode.service.thirdparty; - -import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; -import com.zdxt.enforcementcode.service.thirdparty.impl.PasswordPartyServiceImpl; - -/** - * IPasswordPartyService 接口方法正向流程演示 - *

- * 运行前请确保: - * 1. HSM 密码服务平台已启动且网络可达 - * 2. 下方 BASE_URL 配置为正确的 HSM 服务地址 - * 3. HSM 中已配置好所需的密钥(密钥索引、算法类型等) - *

- * - * @author vincent - * @date 2026-09-22 - */ -public class PasswordPartyDemo { - - /** HSM 密码服务平台地址,按实际环境修改 */ - private static final String BASE_URL = "http://localhost:8080"; - - private static IPasswordPartyService service; - - /** - * 主入口:手动构造 PasswordPartyServiceImpl 实例,依次调用各接口方法验证正向流程 - *

- * 执行顺序: - * 1. 生成随机数 - * 2. 对称加密 → 对称解密(验证互为逆操作) - * 3. SM2签名 - * 4. 非对称加密 → 非对称解密(验证互为逆操作) - * 5. HMAC摘要 - *

- */ - public static void main(String[] args) { - // 构造配置并初始化 Service 实例(不依赖 Spring 容器) - PasswordPartyConfig config = new PasswordPartyConfig(); - config.setBaseUrl(BASE_URL); - service = new PasswordPartyServiceImpl(config); - - System.out.println("========== IPasswordPartyService 正向流程演示 ==========\n"); - - // 1. 生成随机数:验证 HSM 基础连通性 - testGenerateRandom(); - // 2. 对称加密 + 对称解密:使用 SM4 算法,验证加解密互为逆操作 - testSymmetryEncryptAndDecrypt(); - // 3. SM2签名:对摘要数据进行签名,验证签名值非空 - testSM2SignAndVerify(); - // 4. 非对称加密 + 非对称解密:使用 SM2 算法,验证加解密互为逆操作 - testAsymmetricEncryptAndDecrypt(); - // 5. HMAC摘要:使用 SM3 算法计算消息认证码 - testHmacWithIndex(); - - System.out.println("\n========== 全部演示完成 =========="); - } - - /** - * 1. 生成随机数 - */ - private static void testGenerateRandom() { - System.out.println("----- 1. 生成随机数 -----"); - String random = service.generateRandom(10); - System.out.println("随机数(10字节): " + random); - assertNotBlank("random", random); - - String random32 = service.generateRandom(32); - System.out.println("随机数(32字节): " + random32); - assertNotBlank("random32", random32); - System.out.println(); - } - - /** - * 2. 对称加密 + 对称解密(互为逆操作) - */ - private static void testSymmetryEncryptAndDecrypt() { - System.out.println("----- 2. 对称加密 + 对称解密 -----"); - String plainHex = "31323334353637383132333435363738"; - - SymmetryEncryptVo encryptResult = service.symmetryEncrypt(plainHex); - System.out.println("对称加密原文: " + plainHex); - System.out.println("对称加密密文: " + encryptResult.getOutData()); - assertNotBlank("encryptOutData", encryptResult.getOutData()); - - SymmetryEncryptVo decryptResult = service.symmetryDecrypt(null, encryptResult.getOutData()); - System.out.println("对称解密结果: " + decryptResult.getOutData()); - assertNotBlank("decryptOutData", decryptResult.getOutData()); - - if (plainHex.equalsIgnoreCase(decryptResult.getOutData())) { - System.out.println("[PASS] 对称加密/解密互为逆操作,解密结果与原文一致"); - } else { - System.out.println("[WARN] 解密结果与原文不一致,请检查密钥配置"); - } - System.out.println(); - } - - /** - * 3. SM2签名 + SM2验签 - */ - private static void testSM2SignAndVerify() { - System.out.println("----- 3. SM2签名 + SM2验签 -----"); - String plainDataHex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; - - String signValue = service.sm2SignData(plainDataHex); - System.out.println("SM2签名原文(摘要): " + plainDataHex); - System.out.println("SM2签名值: " + signValue); - assertNotBlank("signData", signValue); - - System.out.println("[PASS] SM2签名成功,签名值非空"); - System.out.println(); - } - - /** - * 4. 非对称加密 + 非对称解密 - */ - private static void testAsymmetricEncryptAndDecrypt() { - System.out.println("----- 4. 非对称加密 + 非对称解密 -----"); - String plainHex = "31323334"; - - String publicKey = getTestPublicKey(); - String encryptData = service.externalEncrypt(publicKey, plainHex); - System.out.println("非对称加密原文: " + plainHex); - System.out.println("非对称加密密文: " + encryptData); - assertNotBlank("encryptData", encryptData); - - String decrypted = service.internalDecrypt(encryptData); - System.out.println("非对称解密结果: " + decrypted); - assertNotBlank("decrypted", decrypted); - - if (plainHex.equalsIgnoreCase(decrypted)) { - System.out.println("[PASS] 非对称加密/解密互为逆操作,解密结果与原文一致"); - } else { - System.out.println("[WARN] 解密结果与原文不一致,请检查密钥配置"); - } - System.out.println(); - } - - /** - * 5. HMAC摘要 - */ - private static void testHmacWithIndex() { - System.out.println("----- 5. HMAC摘要 -----"); - String inputDataHex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"; - - String hmac = service.hmacWithIndex(inputDataHex); - System.out.println("HMAC输入摘要: " + inputDataHex); - System.out.println("HMAC输出值: " + hmac); - assertNotBlank("hmac", hmac); - System.out.println("[PASS] HMAC摘要成功,结果非空"); - System.out.println(); - } - - // ======================== 辅助方法 ======================== - - private static String getTestPublicKey() { - // TODO: 替换为 HSM 中实际导出的公钥(Hex 16进制) - return "a746f6b47e9261adbf79e2af77d4b40919c01a85d9b11722c4bdd7cb36fa8ddad68c8abc96d73c986c6de1544c147e0b8208d98d9976facd8f00f312c7c5a90e"; - } - - private static void assertNotBlank(String fieldName, String value) { - if (value == null || value.isBlank()) { - throw new AssertionError("[FAIL] " + fieldName + " 返回值为空"); - } - } - -} diff --git a/zdxt-modules/zdxt-system/pom.xml b/zdxt-modules/zdxt-system/pom.xml index c159f4b6..d2ac3cd2 100644 --- a/zdxt-modules/zdxt-system/pom.xml +++ b/zdxt-modules/zdxt-system/pom.xml @@ -106,10 +106,9 @@ zdxt-common-quartz - org.dromara - zdxt-enforcement-code-common + com.alibaba + fastjson - diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/config/PasswordPartyConfig.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/config/PasswordPartyConfig.java new file mode 100644 index 00000000..25b8d932 --- /dev/null +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/config/PasswordPartyConfig.java @@ -0,0 +1,19 @@ +package org.dromara.system.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-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 d26f3071..9b4b1a44 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 @@ -22,6 +22,7 @@ import org.dromara.system.domain.bo.SysUserProfileBo; import org.dromara.system.domain.vo.ProfileUserVo; import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ICryptoSensitiveHsmService; import org.dromara.system.service.ISysOssService; import org.dromara.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; @@ -48,7 +49,7 @@ public class SysProfileController extends BaseController { private final ISysOssService ossService; @Autowired - private com.zdxt.enforcementcode.service.CryptoSensitiveHsmService cryptoSensitiveHsmService; + private ICryptoSensitiveHsmService ICryptoSensitiveHsmService; /** * 个人信息 @@ -104,7 +105,7 @@ public class SysProfileController extends BaseController { boolean oldPasswordCorrect = false; String bizId = String.valueOf(user.getUserId()); try { - oldPasswordCorrect = cryptoSensitiveHsmService.verifyPassword("sys_user", bizId, bo.getOldPassword()); + oldPasswordCorrect = ICryptoSensitiveHsmService.verifyPassword("sys_user", bizId, bo.getOldPassword()); } catch (Exception e) { log.warn("HSM校验旧密码失败, userId={}, 降级MD5校验", user.getUserId()); } @@ -123,10 +124,20 @@ public class SysProfileController extends BaseController { int rows = DataPermissionHelper.ignore(() -> userService.resetUserPwd(user.getUserId(), newEncrypted)); if (rows > 0) { try { - cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", newEncrypted); + ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", newEncrypted); } catch (Exception e) { log.warn("HSM加密新密码失败, userId={}", user.getUserId(), e); } + try { + SysUserVo updatedUser = userService.selectUserById(user.getUserId()); + ICryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, + "password,phonenumber,certificateNumber", + newEncrypted, + updatedUser.getPhonenumber() != null ? updatedUser.getPhonenumber() : "", + updatedUser.getCertificateNumber() != null ? updatedUser.getCertificateNumber() : ""); + } 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 93a33fa1..27cb8272 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 @@ -4,9 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.lang.tree.Tree; 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; @@ -64,7 +62,7 @@ public class SysUserController extends BaseController { private final ISysTenantService tenantService; @Autowired - private CryptoSensitiveHsmService cryptoSensitiveHsmService; + private ICryptoSensitiveHsmService ICryptoSensitiveHsmService; /** * 获取用户列表 @@ -256,10 +254,21 @@ public class SysUserController extends BaseController { if (rows > 0) { try { String bizId = String.valueOf(user.getUserId()); - cryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); + ICryptoSensitiveHsmService.encryptAndSave("sys_user", bizId, "password", md5Password); } catch (Exception e) { log.warn("HSM加密重置密码失败, userId={}", user.getUserId(), e); } + try { + String bizId = String.valueOf(user.getUserId()); + SysUserVo updatedUser = userService.selectUserById(user.getUserId()); + ICryptoSensitiveHsmService.saveIntegrityHash("sys_user", bizId, + "password,phonenumber,certificateNumber", + md5Password, + updatedUser.getPhonenumber() != null ? updatedUser.getPhonenumber() : "", + updatedUser.getCertificateNumber() != null ? updatedUser.getCertificateNumber() : ""); + } catch (Exception e) { + log.warn("HSM完整性摘要更新失败, userId={}", user.getUserId(), e); + } } return toAjax(rows); } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoIntegrityData.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoIntegrityData.java similarity index 87% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoIntegrityData.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoIntegrityData.java index c6d4ba5a..ea02eaaa 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoIntegrityData.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoIntegrityData.java @@ -1,9 +1,8 @@ -package com.zdxt.enforcementcode.domain.bean; +package org.dromara.system.domain.bean; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; -import lombok.EqualsAndHashCode; import java.io.Serial; import java.util.Date; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoOperationAudit.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoOperationAudit.java similarity index 86% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoOperationAudit.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoOperationAudit.java index ebd30d18..99f742a4 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoOperationAudit.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoOperationAudit.java @@ -1,9 +1,8 @@ -package com.zdxt.enforcementcode.domain.bean; +package org.dromara.system.domain.bean; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; -import lombok.EqualsAndHashCode; import java.io.Serial; import java.util.Date; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoSensitiveData.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoSensitiveData.java similarity index 89% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoSensitiveData.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoSensitiveData.java index 9a4bec50..fa428ec2 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoSensitiveData.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoSensitiveData.java @@ -1,9 +1,8 @@ -package com.zdxt.enforcementcode.domain.bean; +package org.dromara.system.domain.bean; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; -import lombok.EqualsAndHashCode; import java.io.Serial; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoIntegrityDataVo.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoIntegrityDataVo.java similarity index 93% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoIntegrityDataVo.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoIntegrityDataVo.java index 4a271589..556df43d 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoIntegrityDataVo.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoIntegrityDataVo.java @@ -1,10 +1,10 @@ -package com.zdxt.enforcementcode.domain.vo; +package org.dromara.system.domain.vo; import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelProperty; -import com.zdxt.enforcementcode.domain.bean.CryptoIntegrityData; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; +import org.dromara.system.domain.bean.CryptoIntegrityData; import java.io.Serial; import java.io.Serializable; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoOperationAuditVo.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoOperationAuditVo.java similarity index 92% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoOperationAuditVo.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoOperationAuditVo.java index 3e8722d5..71c70a5f 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoOperationAuditVo.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoOperationAuditVo.java @@ -1,10 +1,11 @@ -package com.zdxt.enforcementcode.domain.vo; +package org.dromara.system.domain.vo; import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelProperty; -import com.zdxt.enforcementcode.domain.bean.CryptoOperationAudit; + import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; +import org.dromara.system.domain.bean.CryptoOperationAudit; import java.io.Serial; import java.io.Serializable; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoSensitiveDataVo.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoSensitiveDataVo.java similarity index 94% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoSensitiveDataVo.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoSensitiveDataVo.java index a5d150cb..b0d70f77 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoSensitiveDataVo.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoSensitiveDataVo.java @@ -1,11 +1,11 @@ -package com.zdxt.enforcementcode.domain.vo; +package org.dromara.system.domain.vo; import cn.idev.excel.annotation.ExcelIgnoreUnannotated; import cn.idev.excel.annotation.ExcelProperty; -import com.zdxt.enforcementcode.domain.bean.CryptoSensitiveData; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; +import org.dromara.system.domain.bean.CryptoSensitiveData; import java.io.Serial; import java.io.Serializable; diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/passwordparty/SymmetryEncryptVo.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SymmetryEncryptVo.java similarity index 81% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/passwordparty/SymmetryEncryptVo.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SymmetryEncryptVo.java index a289b3c6..594a3aa1 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/passwordparty/SymmetryEncryptVo.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SymmetryEncryptVo.java @@ -1,4 +1,4 @@ -package com.zdxt.enforcementcode.domain.vo.passwordparty; +package org.dromara.system.domain.vo; import lombok.Data; diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java index e395e00c..31e3a05d 100644 --- a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java @@ -87,6 +87,9 @@ public class SysUserVo implements Serializable { @JsonProperty private String password; + /** 证件号码 */ + @JsonIgnore + private String certificateNumber; /** * 盐加密 */ diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoIntegrityDataMapper.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoIntegrityDataMapper.java similarity index 50% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoIntegrityDataMapper.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoIntegrityDataMapper.java index 4d7ebeb8..25f9ca43 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoIntegrityDataMapper.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoIntegrityDataMapper.java @@ -1,9 +1,8 @@ -package com.zdxt.enforcementcode.mapper; +package org.dromara.system.mapper; - -import com.zdxt.enforcementcode.domain.bean.CryptoIntegrityData; -import com.zdxt.enforcementcode.domain.vo.CryptoIntegrityDataVo; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.system.domain.bean.CryptoIntegrityData; +import org.dromara.system.domain.vo.CryptoIntegrityDataVo; public interface CryptoIntegrityDataMapper extends BaseMapperPlus { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoOperationAuditMapper.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoOperationAuditMapper.java similarity index 51% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoOperationAuditMapper.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoOperationAuditMapper.java index 44adcf8a..32b6e096 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoOperationAuditMapper.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoOperationAuditMapper.java @@ -1,9 +1,9 @@ -package com.zdxt.enforcementcode.mapper; +package org.dromara.system.mapper; -import com.zdxt.enforcementcode.domain.bean.CryptoOperationAudit; -import com.zdxt.enforcementcode.domain.vo.CryptoOperationAuditVo; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.system.domain.bean.CryptoOperationAudit; +import org.dromara.system.domain.vo.CryptoOperationAuditVo; public interface CryptoOperationAuditMapper extends BaseMapperPlus { diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoSensitiveDataMapper.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoSensitiveDataMapper.java similarity index 51% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoSensitiveDataMapper.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoSensitiveDataMapper.java index a54901f8..8f9bf871 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoSensitiveDataMapper.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoSensitiveDataMapper.java @@ -1,8 +1,9 @@ -package com.zdxt.enforcementcode.mapper; +package org.dromara.system.mapper; + -import com.zdxt.enforcementcode.domain.bean.CryptoSensitiveData; -import com.zdxt.enforcementcode.domain.vo.CryptoSensitiveDataVo; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.dromara.system.domain.bean.CryptoSensitiveData; +import org.dromara.system.domain.vo.CryptoSensitiveDataVo; public interface CryptoSensitiveDataMapper extends BaseMapperPlus { diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ICryptoSensitiveHsmService.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ICryptoSensitiveHsmService.java new file mode 100644 index 00000000..622a7d3c --- /dev/null +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ICryptoSensitiveHsmService.java @@ -0,0 +1,67 @@ +package org.dromara.system.service; + +/** + * 密评敏感字段 HSM 加密服务 + *

+ * 通过 HSM 密码服务平台对敏感字段进行加密存储,满足密评合规要求。 + * 手机号/身份证号使用 SM4-CBC 对称加密,密码使用 HMAC-SM3 单向哈希。 + */ +public interface ICryptoSensitiveHsmService { + + /** + * 加密并存储敏感字段(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/thirdparty/IPasswordPartyService.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/IPasswordPartyService.java similarity index 91% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/IPasswordPartyService.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/IPasswordPartyService.java index 94177b3c..43bb0bb5 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/IPasswordPartyService.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/IPasswordPartyService.java @@ -1,6 +1,7 @@ -package com.zdxt.enforcementcode.service.thirdparty; +package org.dromara.system.service; -import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; + +import org.dromara.system.domain.vo.SymmetryEncryptVo; /** * 密码服务平台 @@ -24,7 +25,7 @@ public interface IPasswordPartyService { * @param inputData 加密原文(Hex 16进制) * @return 对称加密结果 */ - SymmetryEncryptVo symmetryEncrypt( String inputData); + SymmetryEncryptVo symmetryEncrypt(String inputData); /** * HSM - 对称解密 diff --git a/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/CryptoSensitiveHsmServiceImpl.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/CryptoSensitiveHsmServiceImpl.java new file mode 100644 index 00000000..1f07f4fb --- /dev/null +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/CryptoSensitiveHsmServiceImpl.java @@ -0,0 +1,195 @@ +package org.dromara.system.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 lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.system.domain.bean.CryptoIntegrityData; +import org.dromara.system.domain.bean.CryptoOperationAudit; +import org.dromara.system.domain.bean.CryptoSensitiveData; +import org.dromara.system.domain.vo.SymmetryEncryptVo; +import org.dromara.system.mapper.CryptoIntegrityDataMapper; +import org.dromara.system.mapper.CryptoOperationAuditMapper; +import org.dromara.system.mapper.CryptoSensitiveDataMapper; +import org.dromara.system.service.ICryptoSensitiveHsmService; +import org.dromara.system.service.IPasswordPartyService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.nio.charset.StandardCharsets; +import java.util.Date; + +@Slf4j +@RequiredArgsConstructor +@Service +public class CryptoSensitiveHsmServiceImpl implements ICryptoSensitiveHsmService { + + 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/impl/PasswordPartyServiceImpl.java b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/PasswordPartyServiceImpl.java similarity index 97% rename from zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java rename to zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/PasswordPartyServiceImpl.java index 420f2f25..983e1ee8 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java +++ b/zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/PasswordPartyServiceImpl.java @@ -1,13 +1,14 @@ -package com.zdxt.enforcementcode.service.thirdparty.impl; +package org.dromara.system.service.impl; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSONObject; -import com.zdxt.enforcementcode.domain.vo.passwordparty.SymmetryEncryptVo; -import com.zdxt.enforcementcode.service.thirdparty.IPasswordPartyService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.exception.base.BaseException; +import org.dromara.system.config.PasswordPartyConfig; +import org.dromara.system.domain.vo.SymmetryEncryptVo; +import org.dromara.system.service.IPasswordPartyService; import org.springframework.stereotype.Service; /** diff --git a/zdxt-web-server/zdxt-admin-web-server/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java b/zdxt-web-server/zdxt-admin-web-server/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java index 9b6ce85a..f769ff01 100644 --- a/zdxt-web-server/zdxt-admin-web-server/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java +++ b/zdxt-web-server/zdxt-admin-web-server/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java @@ -26,6 +26,7 @@ import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.common.web.config.properties.CaptchaProperties; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.vo.SysClientVo; +import org.dromara.system.service.ICryptoSensitiveHsmService; import org.dromara.web.domain.vo.LoginVo; import org.dromara.web.service.IAuthStrategy; import org.dromara.web.service.PasswordService; @@ -47,7 +48,7 @@ public class PasswordAuthStrategy implements IAuthStrategy { private final SysLoginService loginService; private final SysUserMapper userMapper; private final PasswordService passwordService; - private final com.zdxt.enforcementcode.service.CryptoSensitiveHsmService cryptoSensitiveHsmService; + private final ICryptoSensitiveHsmService ICryptoSensitiveHsmService; @Override public LoginVo login(String body, SysClientVo client) { @@ -68,7 +69,7 @@ public class PasswordAuthStrategy implements IAuthStrategy { loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> { String bizId = String.valueOf(user.getUserId()); try { - return !cryptoSensitiveHsmService.verifyPassword("sys_user", bizId, password); + return !ICryptoSensitiveHsmService.verifyPassword("sys_user", bizId, password); } catch (Exception e) { log.warn("HSM密码校验失败, userId={}, 降级使用MD5校验", user.getUserId()); String salt = user.getSalt();