修改数据 mac 校验为真实性验证,做签名。
This commit is contained in:
parent
132c696cf7
commit
045da2a5b5
@ -3,15 +3,23 @@ package com.cisd.tms.infrastructure.persistence.mybatis;
|
|||||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||||
import java.time.LocalDateTime;
|
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 com.cisd.tms.modules.datamac.helper.Sm3MacCalculator;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.apache.ibatis.reflection.MetaObject;
|
import org.apache.ibatis.reflection.MetaObject;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Primary
|
@Primary
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CommonMetaObjectHandler implements MetaObjectHandler {
|
public class CommonMetaObjectHandler implements MetaObjectHandler {
|
||||||
|
|
||||||
|
private final JnaPcieCryptoService sdf;
|
||||||
|
// 密钥对的索引
|
||||||
|
private final int KEYPAIR_INDEX = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void insertFill(MetaObject metaObject) {
|
public void insertFill(MetaObject metaObject) {
|
||||||
if ( metaObject.hasSetter("createTime") ) {
|
if ( metaObject.hasSetter("createTime") ) {
|
||||||
@ -22,11 +30,11 @@ public class CommonMetaObjectHandler implements MetaObjectHandler {
|
|||||||
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
|
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插入时,直接基于当前实体对象计算 MAC
|
// 插入时,直接基于当前实体对象计算签名
|
||||||
if (metaObject.hasSetter("mac")) {
|
if (metaObject.hasSetter("signature")) {
|
||||||
Object entity = metaObject.getOriginalObject();
|
Object entity = metaObject.getOriginalObject();
|
||||||
String mac = Sm3MacCalculator.calculateForEntity(entity);
|
String signature = Sm2EntitySigner.sign(sdf, KEYPAIR_INDEX, entity);
|
||||||
this.strictInsertFill(metaObject, "mac", String.class, mac);
|
this.strictInsertFill(metaObject, "signature", String.class, signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +46,8 @@ public class CommonMetaObjectHandler implements MetaObjectHandler {
|
|||||||
// 插入时,直接基于当前实体对象计算 MAC
|
// 插入时,直接基于当前实体对象计算 MAC
|
||||||
if (metaObject.hasSetter("mac")) {
|
if (metaObject.hasSetter("mac")) {
|
||||||
Object entity = metaObject.getOriginalObject();
|
Object entity = metaObject.getOriginalObject();
|
||||||
String mac = Sm3MacCalculator.calculateForEntity(entity);
|
String signature = Sm2EntitySigner.sign(sdf, KEYPAIR_INDEX, entity);
|
||||||
this.strictInsertFill(metaObject, "mac", String.class, mac);
|
this.strictInsertFill(metaObject, "signature", String.class, signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,8 @@ public class KeyEntity extends BaseEntity {
|
|||||||
private String signData;
|
private String signData;
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|
||||||
// 标记此字段在插入和更新时都需要自动填充
|
// 临时性添加。
|
||||||
|
// 改进方案可以通过直接扩展 BaseEntity 实现。暂时没有全量需求,所以单独添加。
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private String mac;
|
private String signature;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class DataMacEntity {
|
public class ImportantDataEntity {
|
||||||
// 标记此字段在插入和更新时都需要自动填充
|
// 标记此字段在插入和更新时都需要自动填充
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||||
private String mac;
|
private String signature;
|
||||||
}
|
}
|
||||||
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,42 +1,42 @@
|
|||||||
package com.cisd.tms.modules.datamac.interceptor;
|
//package com.cisd.tms.modules.datamac.interceptor;
|
||||||
|
//
|
||||||
|
//
|
||||||
import com.cisd.tms.modules.datamac.entity.DataMacEntity;
|
//import com.cisd.tms.modules.datamac.entity.ImportantDataEntity;
|
||||||
import com.cisd.tms.modules.datamac.helper.Sm3MacCalculator;
|
//import com.cisd.tms.modules.datamac.helper.Sm3MacCalculator;
|
||||||
import org.apache.ibatis.executor.resultset.ResultSetHandler;
|
//import org.apache.ibatis.executor.resultset.ResultSetHandler;
|
||||||
import org.apache.ibatis.plugin.Interceptor;
|
//import org.apache.ibatis.plugin.Interceptor;
|
||||||
import org.apache.ibatis.plugin.Intercepts;
|
//import org.apache.ibatis.plugin.Intercepts;
|
||||||
import org.apache.ibatis.plugin.Invocation;
|
//import org.apache.ibatis.plugin.Invocation;
|
||||||
import org.apache.ibatis.plugin.Signature;
|
//import org.apache.ibatis.plugin.Signature;
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
|
//
|
||||||
import java.sql.Statement;
|
//import java.sql.Statement;
|
||||||
import java.util.List;
|
//import java.util.List;
|
||||||
|
//
|
||||||
|
//
|
||||||
@Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}))
|
//@Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}))
|
||||||
@Component
|
//@Component
|
||||||
public class MacValidationInterceptor implements Interceptor {
|
//public class MacValidationInterceptor implements Interceptor {
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public Object intercept(Invocation invocation) throws Throwable {
|
// public Object intercept(Invocation invocation) throws Throwable {
|
||||||
Object result = invocation.proceed();
|
// Object result = invocation.proceed();
|
||||||
if (result instanceof List) {
|
// if (result instanceof List) {
|
||||||
((List<?>) result).forEach(this::validateEntity);
|
// ((List<?>) result).forEach(this::validateEntity);
|
||||||
} else {
|
// } else {
|
||||||
validateEntity(result);
|
// validateEntity(result);
|
||||||
}
|
// }
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void validateEntity(Object obj) {
|
// private void validateEntity(Object obj) {
|
||||||
if (obj instanceof DataMacEntity) {
|
// if (obj instanceof ImportantDataEntity) {
|
||||||
DataMacEntity entity = (DataMacEntity) obj;
|
// ImportantDataEntity entity = (ImportantDataEntity) obj;
|
||||||
String storedMac = entity.getMac();
|
// String storedMac = entity.getMac();
|
||||||
String calculatedMac = Sm3MacCalculator.calculateForEntity(entity);
|
// String calculatedMac = Sm3MacCalculator.calculateForEntity(entity);
|
||||||
if (!storedMac.equals(calculatedMac)) {
|
// if (!storedMac.equals(calculatedMac)) {
|
||||||
throw new RuntimeException("Data integrity validation failed. The data has been tampered with.");
|
// throw new RuntimeException("Data integrity validation failed. The data has been tampered with.");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
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 com.cisd.tms.modules.log.enums.*;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@ -14,7 +14,7 @@ import java.time.LocalDateTime;
|
|||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@TableName("tms_operation_audit_log")
|
@TableName("tms_operation_audit_log")
|
||||||
public class OperationAuditLogEntity extends DataMacEntity {
|
public class OperationAuditLogEntity extends ImportantDataEntity {
|
||||||
@TableId(type = IdType.ASSIGN_ID)
|
@TableId(type = IdType.ASSIGN_ID)
|
||||||
private Long id;
|
private Long id;
|
||||||
private String logId;
|
private String logId;
|
||||||
|
|||||||
@ -708,5 +708,30 @@ INSERT IGNORE INTO tms_master_key_activate (
|
|||||||
) VALUES (1, true, true);
|
) VALUES (1, true, true);
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE TMS.tms_operation_audit_log ADD mac varchar(100) NULL COMMENT '完整性校验值';
|
ALTER TABLE tms_access_whitelist ADD signature varchar(250) NULL COMMENT '数据真实性签名值';
|
||||||
ALTER TABLE TMS.tms_key_entity ADD mac varchar(100) 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 '数据真实性签名值';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user