Browse Source

优化登录密码校验逻辑

dev-V1.0.9
vincent 1 month ago
parent
commit
004bbbabff
  1. 87
      zdxt-modules/zdxt-enforcement-code-common/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeVirtualUnitServiceImpl.java
  2. 6
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/LoginController.java
  3. 78
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoIntegrityDataBo.java
  4. 83
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoOperationAuditBo.java
  5. 92
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoSensitiveDataBo.java
  6. 12
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/quartz/job/SynUserInfoJob.java
  7. 24
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoIntegrityDataService.java
  8. 24
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoOperationAuditService.java
  9. 24
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoSensitiveDataService.java
  10. 89
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoIntegrityDataServiceImpl.java
  11. 91
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoOperationAuditServiceImpl.java
  12. 91
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveDataServiceImpl.java
  13. 166
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java
  14. 5
      zdxt-modules/zdxt-system/pom.xml
  15. 19
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/config/PasswordPartyConfig.java
  16. 17
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
  17. 17
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
  18. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoIntegrityData.java
  19. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoOperationAudit.java
  20. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/bean/CryptoSensitiveData.java
  21. 4
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoIntegrityDataVo.java
  22. 5
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoOperationAuditVo.java
  23. 4
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/CryptoSensitiveDataVo.java
  24. 2
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SymmetryEncryptVo.java
  25. 3
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
  26. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoIntegrityDataMapper.java
  27. 6
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoOperationAuditMapper.java
  28. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/mapper/CryptoSensitiveDataMapper.java
  29. 67
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ICryptoSensitiveHsmService.java
  30. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/IPasswordPartyService.java
  31. 195
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/CryptoSensitiveHsmServiceImpl.java
  32. 7
      zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/impl/PasswordPartyServiceImpl.java
  33. 5
      zdxt-web-server/zdxt-admin-web-server/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java

87
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.<SysUser>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.<SysUser>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.<SysUser>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<SysUser> uw = Wrappers.<SysUser>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.<SysUser>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.<SysUser>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);
}
}

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

78
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoIntegrityDataBo.java

@ -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;
}

83
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoOperationAuditBo.java

@ -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;
}

92
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bo/CryptoSensitiveDataBo.java

@ -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;
}

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

24
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoIntegrityDataService.java

@ -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<CryptoIntegrityDataVo> queryPageList(CryptoIntegrityDataBo bo, PageQuery pageQuery);
List<CryptoIntegrityDataVo> queryList(CryptoIntegrityDataBo bo);
Boolean insertByBo(CryptoIntegrityDataBo bo);
Boolean updateByBo(CryptoIntegrityDataBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

24
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoOperationAuditService.java

@ -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<CryptoOperationAuditVo> queryPageList(CryptoOperationAuditBo bo, PageQuery pageQuery);
List<CryptoOperationAuditVo> queryList(CryptoOperationAuditBo bo);
Boolean insertByBo(CryptoOperationAuditBo bo);
Boolean updateByBo(CryptoOperationAuditBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

24
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/ICryptoSensitiveDataService.java

@ -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<CryptoSensitiveDataVo> queryPageList(CryptoSensitiveDataBo bo, PageQuery pageQuery);
List<CryptoSensitiveDataVo> queryList(CryptoSensitiveDataBo bo);
Boolean insertByBo(CryptoSensitiveDataBo bo);
Boolean updateByBo(CryptoSensitiveDataBo bo);
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

89
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoIntegrityDataServiceImpl.java

@ -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<CryptoIntegrityDataVo> queryPageList(CryptoIntegrityDataBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CryptoIntegrityData> lqw = buildQueryWrapper(bo);
Page<CryptoIntegrityDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<CryptoIntegrityDataVo> queryList(CryptoIntegrityDataBo bo) {
LambdaQueryWrapper<CryptoIntegrityData> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<CryptoIntegrityData> buildQueryWrapper(CryptoIntegrityDataBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<CryptoIntegrityData> 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<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

91
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoOperationAuditServiceImpl.java

@ -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<CryptoOperationAuditVo> queryPageList(CryptoOperationAuditBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CryptoOperationAudit> lqw = buildQueryWrapper(bo);
Page<CryptoOperationAuditVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<CryptoOperationAuditVo> queryList(CryptoOperationAuditBo bo) {
LambdaQueryWrapper<CryptoOperationAudit> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<CryptoOperationAudit> buildQueryWrapper(CryptoOperationAuditBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<CryptoOperationAudit> 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<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

91
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/CryptoSensitiveDataServiceImpl.java

@ -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<CryptoSensitiveDataVo> queryPageList(CryptoSensitiveDataBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<CryptoSensitiveData> lqw = buildQueryWrapper(bo);
Page<CryptoSensitiveDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
@Override
public List<CryptoSensitiveDataVo> queryList(CryptoSensitiveDataBo bo) {
LambdaQueryWrapper<CryptoSensitiveData> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<CryptoSensitiveData> buildQueryWrapper(CryptoSensitiveDataBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<CryptoSensitiveData> 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<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

166
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/PasswordPartyDemo.java

@ -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 接口方法正向流程演示
* <p>
* 运行前请确保:
* 1. HSM 密码服务平台已启动且网络可达
* 2. 下方 BASE_URL 配置为正确的 HSM 服务地址
* 3. HSM 中已配置好所需的密钥(密钥索引、算法类型等)
* </p>
*
* @author vincent
* @date 2026-09-22
*/
public class PasswordPartyDemo {
/** HSM 密码服务平台地址,按实际环境修改 */
private static final String BASE_URL = "http://localhost:8080";
private static IPasswordPartyService service;
/**
* 主入口:手动构造 PasswordPartyServiceImpl 实例,依次调用各接口方法验证正向流程
* <p>
* 执行顺序:
* 1. 生成随机数
* 2. 对称加密 → 对称解密(验证互为逆操作)
* 3. SM2签名
* 4. 非对称加密 → 非对称解密(验证互为逆操作)
* 5. HMAC摘要
* </p>
*/
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 + " 返回值为空");
}
}
}

5
zdxt-modules/zdxt-system/pom.xml

@ -106,10 +106,9 @@
<artifactId>zdxt-common-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>zdxt-enforcement-code-common</artifactId>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
</project>

19
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;
}
}

17
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("修改密码异常,请联系管理员");

17
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);
}

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoIntegrityData.java → 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;

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoOperationAudit.java → 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;

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/bean/CryptoSensitiveData.java → 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;

4
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoIntegrityDataVo.java → 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;

5
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoOperationAuditVo.java → 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;

4
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/CryptoSensitiveDataVo.java → 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;

2
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/passwordparty/SymmetryEncryptVo.java → 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;

3
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;
/**
* 盐加密
*/

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoIntegrityDataMapper.java → 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<CryptoIntegrityData, CryptoIntegrityDataVo> {

6
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoOperationAuditMapper.java → 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<CryptoOperationAudit, CryptoOperationAuditVo> {

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/CryptoSensitiveDataMapper.java → 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<CryptoSensitiveData, CryptoSensitiveDataVo> {

67
zdxt-modules/zdxt-system/src/main/java/org/dromara/system/service/ICryptoSensitiveHsmService.java

@ -0,0 +1,67 @@
package org.dromara.system.service;
/**
* 密评敏感字段 HSM 加密服务
* <p>
* 通过 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 单向哈希)
* <p>
* 生成随机 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)
* <p>
* 将多个业务字段明文拼接后,调用 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);
}

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/IPasswordPartyService.java → 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 - 对称解密

195
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<CryptoIntegrityData> 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<CryptoSensitiveData> 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<CryptoSensitiveData> 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;
}
}

7
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/thirdparty/impl/PasswordPartyServiceImpl.java → 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;
/**

5
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();

Loading…
Cancel
Save