Merge remote-tracking branch 'origin/V1.00' into V1.00

# Conflicts:
#	src/main/resources/db/migration/V1__tms_schema_full.sql
This commit is contained in:
waner 2026-04-30 16:58:16 +08:00
commit d41e0790bd
11 changed files with 235 additions and 195 deletions

View File

@ -108,6 +108,13 @@
<artifactId>gson</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.10.0</version>
</dependency>
</dependencies>
<build>

View File

@ -4,6 +4,7 @@ public class BackupDataResult {
private byte[] data;
private int length;
private byte[] digest;
public byte[] getData() {
return data;
@ -20,4 +21,8 @@ public class BackupDataResult {
public void setLength(int length) {
this.length = length;
}
public byte[] getDigest() {return digest;}
public void setDigest(byte[] digest) {this.digest = digest;}
}

View File

@ -1,95 +1,14 @@
package com.cisd.tms.integration.crypto.pcie.service;
import com.cisd.tms.integration.crypto.config.CryptoCardProperties;
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
import com.cisd.tms.integration.crypto.pcie.PcieCryptoException;
import com.cisd.tms.integration.crypto.pcie.PcieKeyState;
import com.cisd.tms.integration.crypto.pcie.PcieSessionTemplate;
import com.cisd.tms.integration.crypto.pcie.PcieUserKeyType;
import com.cisd.tms.integration.crypto.pcie.jna.EccCipher;
import com.cisd.tms.integration.crypto.pcie.jna.EccRefPrivateKey;
import com.cisd.tms.integration.crypto.pcie.jna.EccRefPublicKey;
import com.cisd.tms.integration.crypto.pcie.jna.EccSignature;
import com.cisd.tms.integration.crypto.pcie.jna.EnvelopedKeyBlob;
import com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary;
import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPrivateKey;
import com.cisd.tms.integration.crypto.pcie.jna.RsaRefPublicKey;
import com.cisd.tms.integration.crypto.pcie.jna.SdfDeviceInfo;
import com.cisd.tms.integration.crypto.pcie.jna.SdfFirmwareInfo;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceConf;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeKekComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent;
import com.cisd.tms.integration.crypto.pcie.jna.SdfeLoginState;
import com.cisd.tms.integration.crypto.pcie.model.AgreementDataAndKeyEccResult;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
import com.cisd.tms.integration.crypto.pcie.model.ChangePrivateKeyPasswordRequest;
import com.cisd.tms.integration.crypto.pcie.model.DeviceConfResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceCountResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccAgreementSessionKeyResult;
import com.cisd.tms.integration.crypto.pcie.model.EccExternalVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.EccInternalVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ExchangeDigitEnvelopeRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ExportKekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.FileCreateRequest;
import com.cisd.tms.integration.crypto.pcie.model.FileReadRequest;
import com.cisd.tms.integration.crypto.pcie.model.FileWriteRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateAgreementDataAndKeyEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardEccKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateStandardRsaKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithEpkRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithIpkRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyWithKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.GenerateKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacRequest;
import com.cisd.tms.integration.crypto.pcie.model.HmacResult;
import com.cisd.tms.integration.crypto.pcie.model.FirmwareInfoResult;
import com.cisd.tms.integration.crypto.pcie.model.ImportEncKeyPairEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskEccRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyWithIskRsaRequest;
import com.cisd.tms.integration.crypto.pcie.model.ImportKeyPairRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkSignRequest;
import com.cisd.tms.integration.crypto.pcie.model.IkVerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.KekComponentRequest;
import com.cisd.tms.integration.crypto.pcie.model.KeyStatusResult;
import com.cisd.tms.integration.crypto.pcie.model.MacCalcRequest;
import com.cisd.tms.integration.crypto.pcie.model.PrivateKeyAccessRequest;
import com.cisd.tms.integration.crypto.pcie.model.RecoverKekRequest;
import com.cisd.tms.integration.crypto.pcie.model.RecoverUserKeyRequest;
import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPrivateKeyOpRequest;
import com.cisd.tms.integration.crypto.pcie.model.RsaExternalPublicKeyOpRequest;
import com.cisd.tms.integration.crypto.pcie.model.RsaInternalKeyOpRequest;
import com.cisd.tms.integration.crypto.pcie.model.SymmetricCryptoRequest;
import com.cisd.tms.integration.crypto.pcie.model.SymmetricKekCryptoRequest;
import com.cisd.tms.integration.crypto.pcie.model.StandardKeyPairResult;
import com.cisd.tms.integration.crypto.pcie.model.UpdateBackedKeyRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeyDecryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeyEncryptRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeySm2SignRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeySm2VerifyRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeySignRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeyVerifyRequest;
import com.sun.jna.Memory;
import com.cisd.tms.integration.crypto.pcie.*;
import com.cisd.tms.integration.crypto.pcie.jna.*;
import com.cisd.tms.integration.crypto.pcie.model.*;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.function.Supplier;
@ -1687,7 +1606,10 @@ public class JnaPcieCryptoService implements PcieCryptoService {
EccInternalSignRequest signRequest = new EccInternalSignRequest();
signRequest.setKeyIndex(keyIndex);
signRequest.setData(digest);
return withDefaultPrivateKeyAccess(keyIndex, () -> eccInternalSign(signRequest));
BackupDataResult backupDataResult = withDefaultPrivateKeyAccess(keyIndex, () -> eccInternalSign(signRequest));
backupDataResult.setDigest(digest);
return backupDataResult;
}
@Override

View File

@ -29,6 +29,7 @@ public class NetworkConfigController {
@Operation(summary = "获取所有网卡名", description = "获取系统中所有网卡名称")
@GetMapping("/card/eth-names")
@AuditedOperation(module = ModuleCode.DEVICE, action = ActionType.CREATE, summary = "获取所有网卡名")
public ApiResponse<List<String>> getEthDeviceNames() {
return ApiResponse.success(networkConfigService.getEthDeviceNames());
}

View File

@ -3,6 +3,8 @@ package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "Bond分页查询响应数据")
public class BondTableResponse {
@ -59,4 +61,8 @@ public class BondTableResponse {
allowableValues = {"Active", "Inactive"}
)
private String status;
@Schema(description = "Bond对应的物理网卡列表", example = "[\"eth0\", \"eth1\"]")
private List<String> slaveList;
}

View File

@ -662,6 +662,7 @@ public class NetworkConfigService {
}
String bondMode = getBondMode(bondName);
List<String> slaveList = getBondSlaves(bondName);
List<String> conLines = executeCommand(
"nmcli",
@ -680,12 +681,12 @@ public class NetworkConfigService {
boolean hasIp = false;
for (String ipWithPrefix : splitAddressList(ipv4Addresses)) {
resultList.add(createBondTableItem(bondName, bondMode, "IPV4", ipWithPrefix, ipv4Gateway, status));
resultList.add(createBondTableItem(bondName, bondMode, slaveList,"IPV4", ipWithPrefix, ipv4Gateway, status));
hasIp = true;
}
for (String ipWithPrefix : splitAddressList(ipv6Addresses)) {
resultList.add(createBondTableItem(bondName, bondMode, "IPV6", ipWithPrefix, ipv6Gateway, status));
resultList.add(createBondTableItem(bondName, bondMode, slaveList,"IPV6", ipWithPrefix, ipv6Gateway, status));
hasIp = true;
}
@ -1827,6 +1828,7 @@ public class NetworkConfigService {
private BondTableResponse createBondTableItem(
String bondName,
String bondMode,
List<String> slaveList,
String addressType,
String ipWithPrefix,
String gateway,
@ -1835,6 +1837,7 @@ public class NetworkConfigService {
BondTableResponse item = new BondTableResponse();
item.setBondName(bondName);
item.setBondMode(bondMode);
item.setSlaveList(slaveList);
item.setAddressType(addressType);
item.setGateway(gateway == null ? "" : gateway);
item.setStatus(status);

View File

@ -14,6 +14,8 @@ import com.cisd.tms.modules.log.repository.BackupRecordRepository;
import com.cisd.tms.modules.log.repository.OperationAuditLogRepository;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
@ -199,9 +201,9 @@ public class AuditBackupService {
// 对生成zip文件进行哈希和签名
byte[] zipFileBytes = Files.readAllBytes(zipFile.toPath());
byte[] zipFileHash = sm3(zipFileBytes);
byte[] zipFileSign = sign(zipFileHash);
BackupDataResult zipFileBackupData = signWithDigest(zipFileBytes);
byte[] zipFileHash = zipFileBackupData.getDigest();
byte[] zipFileSign = normalize(zipFileBackupData);
record.setFileHash(Base64.getEncoder().encodeToString(zipFileHash));
record.setFileSign(Base64.getEncoder().encodeToString(zipFileSign));
@ -232,39 +234,37 @@ public class AuditBackupService {
ZipOutputStream zos = new ZipOutputStream(fos)) {
StringBuilder csvContent = new StringBuilder();
csvContent.append("日志ID,发生时间,操作角色,认证等级,业务模块,操作动作,操作结果,来源IP,操作摘要,失败原因,审计状态,审计结果,审计人,审计时间,防篡改摘要(SM3),签名值(SM2),创建时间\n");
List<OperationAuditLogEntity> logList = operationAuditLogRepository.findAll().orElseGet(ArrayList::new);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (OperationAuditLogEntity auditLog : logList) {
String summary = escapeCSV(auditLog.getSummary());
String errorMsg = escapeCSV(auditLog.getErrorMessage());
String actionType = auditLog.getActionType() != null ? auditLog.getActionType().name() : "";
String result = auditLog.getOperationResult() != null ? auditLog.getOperationResult().name() : "";
String occurredTime = auditLog.getOccurredAt() != null ? auditLog.getOccurredAt().format(formatter) : "";
String auditedTime = auditLog.getAuditedAt() != null ? auditLog.getAuditedAt().format(formatter) : "";
String createdTime = auditLog.getCreateTime() != null ? auditLog.getCreateTime().format(formatter) : "";
String line = String.format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
auditLog.getLogId(),
occurredTime,
auditLog.getOperatorRoleCode() != null ? auditLog.getOperatorRoleCode() : "",
auditLog.getOperatorAuthLevel() != null ? auditLog.getOperatorAuthLevel() : "",
auditLog.getModuleCode(),
actionType,
result,
auditLog.getRemoteIp(),
summary,
errorMsg,
auditLog.getAuditStatus() != null ? auditLog.getAuditStatus() : "",
auditLog.getAuditResult() != null ? auditLog.getAuditResult() : "",
auditLog.getAuditedBy() != null ? auditLog.getAuditedBy() : "",
auditedTime,
auditLog.getPayloadHash(),
auditLog.getSignValue(),
createdTime
);
csvContent.append(line);
CSVFormat format = CSVFormat.DEFAULT.builder()
.setHeader("日志ID", "发生时间", "操作角色", "认证等级", "业务模块",
"操作动作", "操作结果", "来源IP", "操作摘要", "失败原因",
"审计状态", "审计结果", "审计人", "审计时间",
"防篡改摘要(SM3)", "签名值(SM2)", "创建时间")
.build();
try (CSVPrinter printer = format.print(csvContent)) {
for (OperationAuditLogEntity auditLog : logList) {
printer.printRecord(
auditLog.getLogId(),
formatDateTime(auditLog.getOccurredAt(), formatter),
nullToEmpty(auditLog.getOperatorRoleCode()),
nullToEmpty(auditLog.getOperatorAuthLevel()),
auditLog.getModuleCode(),
auditLog.getActionType(),
auditLog.getOperationResult(),
auditLog.getRemoteIp(),
auditLog.getSummary(),
auditLog.getErrorMessage(),
nullToEmpty(auditLog.getAuditStatus()),
nullToEmpty(auditLog.getAuditResult()),
nullToEmpty(auditLog.getAuditedBy()),
formatDateTime(auditLog.getAuditedAt(), formatter),
auditLog.getPayloadHash(),
auditLog.getSignValue(),
formatDateTime(auditLog.getCreateTime(), formatter)
);
}
}
// 加密
@ -339,9 +339,9 @@ public class AuditBackupService {
// 对生成zip文件进行哈希和签名
byte[] zipFileBytes = Files.readAllBytes(zipFile.toPath());
byte[] zipFileHash = sm3(zipFileBytes);
byte[] zipFileSign = sign(zipFileHash);
BackupDataResult zipFileBackupData = signWithDigest(zipFileBytes);
byte[] zipFileHash = zipFileBackupData.getDigest();
byte[] zipFileSign = normalize(zipFileBackupData);
record.setFileHash(Base64.getEncoder().encodeToString(zipFileHash));
record.setFileSign(Base64.getEncoder().encodeToString(zipFileSign));
@ -378,10 +378,28 @@ public class AuditBackupService {
}
UserKeySignRequest request = new UserKeySignRequest();
request.setKeyIndex(1);
request.setData(sm3(dataToSign));
request.setData(dataToSign);
return normalize(pcieCryptoService.userKeySignWithSm3(request));
}
private BackupDataResult signWithDigest(byte[] dataToSign){
if (dataToSign == null) {
throw new IllegalArgumentException("dataToSign is required");
}
UserKeySignRequest request = new UserKeySignRequest();
request.setKeyIndex(1);
request.setData(dataToSign);
return pcieCryptoService.userKeySignWithSm3(request);
}
private String formatDateTime(LocalDateTime dateTime, DateTimeFormatter formatter) {
return dateTime != null ? dateTime.format(formatter) : "";
}
private String nullToEmpty(Object obj) {
return obj != null ? obj.toString() : "";
}
private String escapeCSV(String str) {
if (str == null) {
return "";

View File

@ -16,6 +16,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -29,6 +32,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@ -94,7 +98,7 @@ public class AuditLogRestoreService {
// //todo 验签
UserKeyVerifyRequest userKeyVerifyRequest = new UserKeyVerifyRequest();
userKeyVerifyRequest.setKeyIndex(1);
userKeyVerifyRequest.setData(sm3(signatureSource));
userKeyVerifyRequest.setData(signatureSource);
userKeyVerifyRequest.setSignature(signatureBytes);
// try {
// pcieCryptoService.userKeyVerifyWithSm3(userKeyVerifyRequest);
@ -140,10 +144,9 @@ public class AuditLogRestoreService {
List<OperationAuditLogEntity> pendingInsertList = new ArrayList<>();
String[] lines = csvContent.split("\n");
totalCount = lines.length - 1;
List<OperationAuditLogEntity> parsedLogs = parseCsvToEntities(lines);
List<OperationAuditLogEntity> parsedLogs = parseCsvToEntities(csvContent);
totalCount = parsedLogs.size();
List<String> incomingSignValues = parsedLogs.stream()
.map(OperationAuditLogEntity::getSignValue)
.collect(Collectors.toList());
@ -232,56 +235,77 @@ public class AuditLogRestoreService {
outputStream.write(safeData);
}
//todo后续改转义
private List<OperationAuditLogEntity> parseCsvToEntities(String[] lines) {
private List<OperationAuditLogEntity> parseCsvToEntities(String csvContent) {
List<OperationAuditLogEntity> list = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (int i = 1; i < lines.length; i++) {
if (lines[i].trim().isEmpty()) continue;
String[] cols = lines[i].split(",", -1);
OperationAuditLogEntity entity = new OperationAuditLogEntity();
entity.setLogId(cols[0]);
try (StringReader reader = new StringReader(csvContent);
CSVParser parser = CSVFormat.DEFAULT.builder()
.setHeader()
.setSkipHeaderRecord(true)
.build()
.parse(reader)) {
if (!cols[1].isEmpty()) {
entity.setOccurredAt(LocalDateTime.parse(cols[1], formatter));
for (CSVRecord record : parser) {
if (record.size() < 17) {
throw new IllegalArgumentException("恢复数据异常");
}
OperationAuditLogEntity entity = new OperationAuditLogEntity();
entity.setLogId(record.get(0));
String occurredAt = record.get(1);
if (!occurredAt.isEmpty()) {
entity.setOccurredAt(LocalDateTime.parse(occurredAt, formatter));
}
String roleCode = record.get(2);
if (!roleCode.isEmpty()) entity.setOperatorRoleCode(OperatorRoleCode.valueOf(roleCode));
String authLevel = record.get(3);
if (!authLevel.isEmpty()) entity.setOperatorAuthLevel(AuthLevel.valueOf(authLevel));
String moduleCode = record.get(4);
if (!moduleCode.isEmpty()) entity.setModuleCode(ModuleCode.valueOf(moduleCode));
String actionType = record.get(5);
if (!actionType.isEmpty()) entity.setActionType(ActionType.valueOf(actionType));
String operationResult = record.get(6);
if (!operationResult.isEmpty()) entity.setOperationResult(OperationResult.valueOf(operationResult));
entity.setRemoteIp(record.get(7));
entity.setSummary(record.get(8));
entity.setErrorMessage(record.get(9));
String auditStatus = record.get(10);
if (!auditStatus.isEmpty()) entity.setAuditStatus(AuditStatus.valueOf(auditStatus));
String auditResult = record.get(11);
if (!auditResult.isEmpty()) entity.setAuditResult(AuditResult.valueOf(auditResult));
entity.setAuditedBy(record.get(12));
String auditedAt = record.get(13);
if (!auditedAt.isEmpty()) {
entity.setAuditedAt(LocalDateTime.parse(auditedAt, formatter));
}
entity.setPayloadHash(record.get(14));
entity.setSignValue(record.get(15));
String createTime = record.get(16);
if (!createTime.isEmpty()) {
entity.setCreateTime(LocalDateTime.parse(createTime, formatter));
}
list.add(entity);
}
if (!cols[2].isEmpty()) entity.setOperatorRoleCode(OperatorRoleCode.valueOf(cols[2]));
if (!cols[3].isEmpty()) entity.setOperatorAuthLevel(AuthLevel.valueOf(cols[3]));
if (!cols[4].isEmpty()) entity.setModuleCode(ModuleCode.valueOf(cols[4]));
if (!cols[5].isEmpty()) entity.setActionType(ActionType.valueOf(cols[5]));
if (!cols[6].isEmpty()) entity.setOperationResult(OperationResult.valueOf(cols[6]));
entity.setRemoteIp(cols[7]);
entity.setSummary(cols[8].replace("\"\"", "\"").replaceAll("^\"|\"$", ""));
entity.setErrorMessage(cols[9].replace("\"\"", "\"").replaceAll("^\"|\"$", ""));
if (!cols[10].isEmpty()) entity.setAuditStatus(AuditStatus.valueOf(cols[10]));
if (!cols[11].isEmpty()) entity.setAuditResult(AuditResult.valueOf(cols[11]));
entity.setAuditedBy(cols[12]);
if (!cols[13].isEmpty()) {
entity.setAuditedAt(LocalDateTime.parse(cols[13], formatter));
}
entity.setPayloadHash(cols[14]);
entity.setSignValue(cols[15]);
if (!cols[16].isEmpty()) {
entity.setCreateTime(LocalDateTime.parse(cols[16], formatter));
}
list.add(entity);
} catch (IOException e) {
throw new RuntimeException("CSV 解析失败", e);
}
return list;
}

View File

@ -190,17 +190,9 @@ public class OperationAuditService {
//
// String payload = auditSigner.buildAuditPayload(existLog);
//
// //计算SM3哈希
// DigestRequest request = new DigestRequest();
// request.setAlgId(Gm0018AlgorithmIds.SM3);
// request.setData(payload.getBytes(StandardCharsets.UTF_8));
// BackupDataResult payloadHash = pcieCryptoService.digest(request);
//
//
// //todo 验签
// UserKeyVerifyRequest userKeyVerifyRequest = new UserKeyVerifyRequest();
// userKeyVerifyRequest.setKeyIndex(1);
// userKeyVerifyRequest.setData(payloadHash.getData());
// userKeyVerifyRequest.setData(payload.getBytes(StandardCharsets.UTF_8));
// userKeyVerifyRequest.setSignature(decodeBlob(signValue, "signature is invalid"));
// try {
// pcieCryptoService.userKeyVerifyWithSm3(userKeyVerifyRequest);

View File

@ -1,8 +1,6 @@
package com.cisd.tms.modules.log.service;
import com.cisd.tms.integration.crypto.pcie.Gm0018AlgorithmIds;
import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult;
import com.cisd.tms.integration.crypto.pcie.model.DigestRequest;
import com.cisd.tms.integration.crypto.pcie.model.UserKeySignRequest;
import com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService;
import com.cisd.tms.modules.log.entity.OperationAuditLogEntity;
@ -37,24 +35,18 @@ public class OperationAuditSigner {
}
//todo 生成签名
//生成签名
public void signEntity(OperationAuditLogEntity entity) {
String payload = buildAuditPayload(entity);
//计算SM3哈希
DigestRequest request = new DigestRequest();
request.setAlgId(Gm0018AlgorithmIds.SM3);
request.setData(payload.getBytes(StandardCharsets.UTF_8));
BackupDataResult payloadHash = pcieCryptoService.digest(request);
entity.setPayloadHash(Base64.getEncoder().encodeToString(payloadHash.getData()));
//计算 SM2 签名值
UserKeySignRequest userKeySignRequest = new UserKeySignRequest();
userKeySignRequest.setData(payloadHash.getData());
userKeySignRequest.setData(payload.getBytes(StandardCharsets.UTF_8));
userKeySignRequest.setKeyIndex(1);
BackupDataResult sign = pcieCryptoService.userKeySignWithSm3(userKeySignRequest );
BackupDataResult sign = pcieCryptoService.userKeySignWithSm3(userKeySignRequest);
entity.setSignValue(Base64.getEncoder().encodeToString(sign.getData()));
entity.setPayloadHash(Base64.getEncoder().encodeToString(sign.getDigest()));
}

View File

@ -645,3 +645,73 @@ CREATE TABLE IF NOT EXISTS t_certificate_crl_revoked (
KEY idx_t_certificate_crl_revoked_subject_dn (subject_dn(512)),
KEY idx_t_certificate_crl_revoked_revocation_time (revocation_time)
);
-- -----------------------------------------------------------------------------
-- 日志表
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS tms_operation_audit_log (
id BIGINT PRIMARY KEY,
log_id VARCHAR(64) NOT NULL COMMENT '日志唯一标识',
operator_role_code VARCHAR(64) NOT NULL COMMENT '操作角色编码',
operator_auth_level VARCHAR(32) NULL COMMENT '操作时认证等级',
module_code VARCHAR(32) NOT NULL COMMENT '业务模块',
action_type VARCHAR(32) NOT NULL COMMENT '操作动作',
remote_ip VARCHAR(64) NULL COMMENT '来源IP',
operation_result VARCHAR(16) NOT NULL COMMENT '操作结果: SUCCESS/FAILED/DENIED',
summary VARCHAR(512) NOT NULL COMMENT '操作摘要',
error_message VARCHAR(1024) NULL COMMENT '失败原因',
audit_status VARCHAR(16) NOT NULL COMMENT '审计状态: PENDING/REVIEWED',
audit_result VARCHAR(16) NULL COMMENT '审计结果: PASS/REJECT/NEED_VERIFY',
audit_comment VARCHAR(1024) NULL COMMENT '审计意见',
audited_by VARCHAR(64) NULL COMMENT '审计人',
audited_at DATETIME(3) NULL COMMENT '审计时间',
payload_hash VARCHAR(128) NOT NULL COMMENT 'SM3摘要',
sign_value TEXT NOT NULL COMMENT 'SM2签名值',
occurred_at DATETIME(3) NOT NULL COMMENT '操作发生时间',
create_time DATETIME(3) NOT NULL COMMENT '落库时间',
UNIQUE KEY uk_tms_operation_audit_log_log_id (log_id),
KEY idx_tms_operation_audit_log_role_code (operator_role_code),
KEY idx_tms_operation_audit_log_module_code (module_code),
KEY idx_tms_operation_audit_log_action_type (action_type),
KEY idx_tms_operation_audit_log_result (operation_result),
KEY idx_tms_operation_audit_log_audit_status (audit_status),
KEY idx_tms_operation_audit_log_occurred_at (occurred_at)
);
-- -----------------------------------------------------------------------------
-- 日志备份记录表
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS tms_log_backup_record (
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
record_id VARCHAR(64) NOT NULL COMMENT '备份记录ID',
file_name VARCHAR(255) NOT NULL COMMENT '备份文件名',
backup_type VARCHAR(32) NOT NULL COMMENT '备份类型AUTO/MANUAL',
file_path VARCHAR(500) NOT NULL COMMENT '文件存储路径',
file_hash VARCHAR(128) NOT NULL COMMENT '文件哈希值',
file_sign VARCHAR(256) DEFAULT NULL COMMENT '文件签名',
backup_result VARCHAR(32) NOT NULL COMMENT '备份结果SUCCESS/FAILED',
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
sign_data TEXT DEFAULT NULL COMMENT '其他字段签名',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_record_id` (`record_id`),
KEY `idx_create_time` (`create_time`),
KEY `idx_backup_type` (`backup_type`)
)
-- -----------------------------------------------------------------------------
-- 日志备份配置表
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS tms_backup_config (
id int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
enable tinyint(4) NOT NULL DEFAULT '0' COMMENT '启用状态 1:启用 0:禁用',
cron_exp varchar(64) DEFAULT NULL COMMENT 'Cron表达式',
retention_count int(11) DEFAULT '1' COMMENT '保留份数',
last_backup_time datetime DEFAULT NULL COMMENT '上次执行时间',
sign_data varchar(255) NOT NULL COMMENT '其他字段的签名值',
PRIMARY KEY (`id`)
)