From 045da2a5b5311b16b7ba802d16e1a0b1e76e171e Mon Sep 17 00:00:00 2001 From: cheney Date: Wed, 20 May 2026 15:26:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE=20mac=20?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E4=B8=BA=E7=9C=9F=E5=AE=9E=E6=80=A7=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=EF=BC=8C=E5=81=9A=E7=AD=BE=E5=90=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatis/CommonMetaObjectHandler.java | 20 +++-- .../tms/modules/cert/entity/KeyEntity.java | 5 +- ...acEntity.java => ImportantDataEntity.java} | 4 +- .../datamac/helper/Sm2EntitySigner.java | 50 +++++++++++ .../interceptor/MacValidationInterceptor.java | 84 +++++++++---------- .../log/entity/OperationAuditLogEntity.java | 4 +- .../db/migration/V1__tms_schema_full.sql | 29 ++++++- 7 files changed, 140 insertions(+), 56 deletions(-) rename src/main/java/com/cisd/tms/modules/datamac/entity/{DataMacEntity.java => ImportantDataEntity.java} (81%) create mode 100644 src/main/java/com/cisd/tms/modules/datamac/helper/Sm2EntitySigner.java diff --git a/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java b/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java index bb9f3e9..95e125f 100644 --- a/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java +++ b/src/main/java/com/cisd/tms/infrastructure/persistence/mybatis/CommonMetaObjectHandler.java @@ -3,15 +3,23 @@ package com.cisd.tms.infrastructure.persistence.mybatis; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import java.time.LocalDateTime; +import com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService; +import com.cisd.tms.modules.datamac.helper.Sm2EntitySigner; import com.cisd.tms.modules.datamac.helper.Sm3MacCalculator; +import lombok.RequiredArgsConstructor; import org.apache.ibatis.reflection.MetaObject; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @Component @Primary +@RequiredArgsConstructor public class CommonMetaObjectHandler implements MetaObjectHandler { + private final JnaPcieCryptoService sdf; + // 密钥对的索引 + private final int KEYPAIR_INDEX = 1; + @Override public void insertFill(MetaObject metaObject) { if ( metaObject.hasSetter("createTime") ) { @@ -22,11 +30,11 @@ public class CommonMetaObjectHandler implements MetaObjectHandler { this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); } - // 插入时,直接基于当前实体对象计算 MAC - if (metaObject.hasSetter("mac")) { + // 插入时,直接基于当前实体对象计算签名 + if (metaObject.hasSetter("signature")) { Object entity = metaObject.getOriginalObject(); - String mac = Sm3MacCalculator.calculateForEntity(entity); - this.strictInsertFill(metaObject, "mac", String.class, mac); + String signature = Sm2EntitySigner.sign(sdf, KEYPAIR_INDEX, entity); + this.strictInsertFill(metaObject, "signature", String.class, signature); } } @@ -38,8 +46,8 @@ public class CommonMetaObjectHandler implements MetaObjectHandler { // 插入时,直接基于当前实体对象计算 MAC if (metaObject.hasSetter("mac")) { Object entity = metaObject.getOriginalObject(); - String mac = Sm3MacCalculator.calculateForEntity(entity); - this.strictInsertFill(metaObject, "mac", String.class, mac); + String signature = Sm2EntitySigner.sign(sdf, KEYPAIR_INDEX, entity); + this.strictInsertFill(metaObject, "signature", String.class, signature); } } } diff --git a/src/main/java/com/cisd/tms/modules/cert/entity/KeyEntity.java b/src/main/java/com/cisd/tms/modules/cert/entity/KeyEntity.java index e5bf231..0456dd4 100644 --- a/src/main/java/com/cisd/tms/modules/cert/entity/KeyEntity.java +++ b/src/main/java/com/cisd/tms/modules/cert/entity/KeyEntity.java @@ -29,7 +29,8 @@ public class KeyEntity extends BaseEntity { private String signData; private String createBy; - // 标记此字段在插入和更新时都需要自动填充 + // 临时性添加。 + // 改进方案可以通过直接扩展 BaseEntity 实现。暂时没有全量需求,所以单独添加。 @TableField(fill = FieldFill.INSERT_UPDATE) - private String mac; + private String signature; } diff --git a/src/main/java/com/cisd/tms/modules/datamac/entity/DataMacEntity.java b/src/main/java/com/cisd/tms/modules/datamac/entity/ImportantDataEntity.java similarity index 81% rename from src/main/java/com/cisd/tms/modules/datamac/entity/DataMacEntity.java rename to src/main/java/com/cisd/tms/modules/datamac/entity/ImportantDataEntity.java index 9611ab5..df69b19 100644 --- a/src/main/java/com/cisd/tms/modules/datamac/entity/DataMacEntity.java +++ b/src/main/java/com/cisd/tms/modules/datamac/entity/ImportantDataEntity.java @@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; @Data -public class DataMacEntity { +public class ImportantDataEntity { // 标记此字段在插入和更新时都需要自动填充 @TableField(fill = FieldFill.INSERT_UPDATE) - private String mac; + private String signature; } \ No newline at end of file diff --git a/src/main/java/com/cisd/tms/modules/datamac/helper/Sm2EntitySigner.java b/src/main/java/com/cisd/tms/modules/datamac/helper/Sm2EntitySigner.java new file mode 100644 index 0000000..7087f40 --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/datamac/helper/Sm2EntitySigner.java @@ -0,0 +1,50 @@ +package com.cisd.tms.modules.datamac.helper; + +import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult; +import com.cisd.tms.integration.crypto.pcie.model.UserKeySm2SignRequest; +import com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService; + +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Comparator; + +public class Sm2EntitySigner { + + private static final byte[] DEFAULT_SM2_USER_ID = "1234567812345678".getBytes(StandardCharsets.UTF_8); + + public static String sign(JnaPcieCryptoService sdf, int keyIdx, Object entity){ + // 1. 获取所有字段并按字段名排序,保证不同实体计算的顺序一致 + Field[] fields = entity.getClass().getDeclaredFields(); + Arrays.sort(fields, Comparator.comparing(Field::getName)); + + // 2. 构建待摘要的数据 + StringBuilder dataBuilder = new StringBuilder(); + for (Field field : fields) { + // 排除 signature 字段自身 + if ("signature".equals(field.getName())) { + continue; + } + try { + field.setAccessible(true); + Object value = field.get(entity); + dataBuilder.append(field.getName()).append("=") + .append(value != null ? value.toString() : "") + .append(";"); + } catch (IllegalAccessException e) { + // 适当的日志记录 + throw new RuntimeException("Failed to read field: " + field.getName(), e); + } + } + + UserKeySm2SignRequest request = new UserKeySm2SignRequest(); + request.setKeyIndex(keyIdx); + request.setData(dataBuilder.toString().getBytes(StandardCharsets.UTF_8)); + request.setUserId(DEFAULT_SM2_USER_ID); + + BackupDataResult result = sdf.userKeySignWithSm2Sm3(request); + + // Base64 格式返回 + return java.util.Base64.getEncoder().encodeToString(result.getData()); + } +} diff --git a/src/main/java/com/cisd/tms/modules/datamac/interceptor/MacValidationInterceptor.java b/src/main/java/com/cisd/tms/modules/datamac/interceptor/MacValidationInterceptor.java index 2fb25d9..6a8d6af 100644 --- a/src/main/java/com/cisd/tms/modules/datamac/interceptor/MacValidationInterceptor.java +++ b/src/main/java/com/cisd/tms/modules/datamac/interceptor/MacValidationInterceptor.java @@ -1,42 +1,42 @@ -package com.cisd.tms.modules.datamac.interceptor; - - -import com.cisd.tms.modules.datamac.entity.DataMacEntity; -import com.cisd.tms.modules.datamac.helper.Sm3MacCalculator; -import org.apache.ibatis.executor.resultset.ResultSetHandler; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.plugin.Intercepts; -import org.apache.ibatis.plugin.Invocation; -import org.apache.ibatis.plugin.Signature; -import org.springframework.stereotype.Component; - -import java.sql.Statement; -import java.util.List; - - -@Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})) -@Component -public class MacValidationInterceptor implements Interceptor { - - @Override - public Object intercept(Invocation invocation) throws Throwable { - Object result = invocation.proceed(); - if (result instanceof List) { - ((List) result).forEach(this::validateEntity); - } else { - validateEntity(result); - } - return result; - } - - private void validateEntity(Object obj) { - if (obj instanceof DataMacEntity) { - DataMacEntity entity = (DataMacEntity) obj; - String storedMac = entity.getMac(); - String calculatedMac = Sm3MacCalculator.calculateForEntity(entity); - if (!storedMac.equals(calculatedMac)) { - throw new RuntimeException("Data integrity validation failed. The data has been tampered with."); - } - } - } -} \ No newline at end of file +//package com.cisd.tms.modules.datamac.interceptor; +// +// +//import com.cisd.tms.modules.datamac.entity.ImportantDataEntity; +//import com.cisd.tms.modules.datamac.helper.Sm3MacCalculator; +//import org.apache.ibatis.executor.resultset.ResultSetHandler; +//import org.apache.ibatis.plugin.Interceptor; +//import org.apache.ibatis.plugin.Intercepts; +//import org.apache.ibatis.plugin.Invocation; +//import org.apache.ibatis.plugin.Signature; +//import org.springframework.stereotype.Component; +// +//import java.sql.Statement; +//import java.util.List; +// +// +//@Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})) +//@Component +//public class MacValidationInterceptor implements Interceptor { +// +// @Override +// public Object intercept(Invocation invocation) throws Throwable { +// Object result = invocation.proceed(); +// if (result instanceof List) { +// ((List) result).forEach(this::validateEntity); +// } else { +// validateEntity(result); +// } +// return result; +// } +// +// private void validateEntity(Object obj) { +// if (obj instanceof ImportantDataEntity) { +// ImportantDataEntity entity = (ImportantDataEntity) obj; +// String storedMac = entity.getMac(); +// String calculatedMac = Sm3MacCalculator.calculateForEntity(entity); +// if (!storedMac.equals(calculatedMac)) { +// throw new RuntimeException("Data integrity validation failed. The data has been tampered with."); +// } +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/com/cisd/tms/modules/log/entity/OperationAuditLogEntity.java b/src/main/java/com/cisd/tms/modules/log/entity/OperationAuditLogEntity.java index 633cce5..617cbf6 100644 --- a/src/main/java/com/cisd/tms/modules/log/entity/OperationAuditLogEntity.java +++ b/src/main/java/com/cisd/tms/modules/log/entity/OperationAuditLogEntity.java @@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.cisd.tms.modules.datamac.entity.DataMacEntity; +import com.cisd.tms.modules.datamac.entity.ImportantDataEntity; import com.cisd.tms.modules.log.enums.*; import lombok.Data; import lombok.experimental.Accessors; @@ -14,7 +14,7 @@ import java.time.LocalDateTime; @Data @Accessors(chain = true) @TableName("tms_operation_audit_log") -public class OperationAuditLogEntity extends DataMacEntity { +public class OperationAuditLogEntity extends ImportantDataEntity { @TableId(type = IdType.ASSIGN_ID) private Long id; private String logId; diff --git a/src/main/resources/db/migration/V1__tms_schema_full.sql b/src/main/resources/db/migration/V1__tms_schema_full.sql index cb8c691..0decc94 100644 --- a/src/main/resources/db/migration/V1__tms_schema_full.sql +++ b/src/main/resources/db/migration/V1__tms_schema_full.sql @@ -708,5 +708,30 @@ INSERT IGNORE INTO tms_master_key_activate ( ) VALUES (1, true, true); -ALTER TABLE TMS.tms_operation_audit_log ADD mac varchar(100) NULL COMMENT '完整性校验值'; -ALTER TABLE TMS.tms_key_entity ADD mac varchar(100) NULL COMMENT '完整性校验值'; +ALTER TABLE tms_access_whitelist ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_auth_audit_log ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_auth_challenge ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_auth_full_account ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_auth_session ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_backup_config ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_certificate ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_certificate_crl ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_certificate_crl_import_task ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_certificate_crl_revoked ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_device_node ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_device_software_version ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_file_record ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_init_task ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_init_task_step ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_key_entity ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_log_backup_record ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_master_key_activate ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_operation_audit_log ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_replay_nonce ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_resource_backup_task ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_resource_restore_task ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_role_account ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_role_ukey_binding ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_security_event ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_trusted_cert ADD signature varchar(250) NULL COMMENT '数据真实性签名值'; +ALTER TABLE tms_upgrade_task ADD signature varchar(250) NULL COMMENT '数据真实性签名值';