diff --git a/pom.xml b/pom.xml
index 2127f8c..d85b796 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,6 +108,13 @@
gson
2.13.2
+
+
+
+ org.apache.commons
+ commons-csv
+ 1.10.0
+
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java
index c064e61..068f83e 100644
--- a/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/model/BackupDataResult.java
@@ -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;}
}
diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java
index b0209a5..13a2706 100644
--- a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java
+++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java
@@ -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
diff --git a/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java b/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java
index e0d2964..f0fae4c 100644
--- a/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java
+++ b/src/main/java/com/cisd/tms/modules/device/controller/NetworkConfigController.java
@@ -29,6 +29,7 @@ public class NetworkConfigController {
@Operation(summary = "获取所有网卡名", description = "获取系统中所有网卡名称")
@GetMapping("/card/eth-names")
+ @AuditedOperation(module = ModuleCode.DEVICE, action = ActionType.CREATE, summary = "获取所有网卡名")
public ApiResponse> getEthDeviceNames() {
return ApiResponse.success(networkConfigService.getEthDeviceNames());
}
diff --git a/src/main/java/com/cisd/tms/modules/device/dto/network/BondTableResponse.java b/src/main/java/com/cisd/tms/modules/device/dto/network/BondTableResponse.java
index b9c9a6d..1a491f4 100644
--- a/src/main/java/com/cisd/tms/modules/device/dto/network/BondTableResponse.java
+++ b/src/main/java/com/cisd/tms/modules/device/dto/network/BondTableResponse.java
@@ -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 slaveList;
}
\ No newline at end of file
diff --git a/src/main/java/com/cisd/tms/modules/device/service/NetworkConfigService.java b/src/main/java/com/cisd/tms/modules/device/service/NetworkConfigService.java
index 25f0dc5..a65e83a 100644
--- a/src/main/java/com/cisd/tms/modules/device/service/NetworkConfigService.java
+++ b/src/main/java/com/cisd/tms/modules/device/service/NetworkConfigService.java
@@ -662,6 +662,7 @@ public class NetworkConfigService {
}
String bondMode = getBondMode(bondName);
+ List slaveList = getBondSlaves(bondName);
List 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 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);
diff --git a/src/main/java/com/cisd/tms/modules/log/service/AuditBackupService.java b/src/main/java/com/cisd/tms/modules/log/service/AuditBackupService.java
index 1c45b7d..2f75b44 100644
--- a/src/main/java/com/cisd/tms/modules/log/service/AuditBackupService.java
+++ b/src/main/java/com/cisd/tms/modules/log/service/AuditBackupService.java
@@ -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 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 "";
diff --git a/src/main/java/com/cisd/tms/modules/log/service/AuditLogRestoreService.java b/src/main/java/com/cisd/tms/modules/log/service/AuditLogRestoreService.java
index 08b0648..2226a71 100644
--- a/src/main/java/com/cisd/tms/modules/log/service/AuditLogRestoreService.java
+++ b/src/main/java/com/cisd/tms/modules/log/service/AuditLogRestoreService.java
@@ -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 pendingInsertList = new ArrayList<>();
- String[] lines = csvContent.split("\n");
- totalCount = lines.length - 1;
- List parsedLogs = parseCsvToEntities(lines);
+ List parsedLogs = parseCsvToEntities(csvContent);
+ totalCount = parsedLogs.size();
List incomingSignValues = parsedLogs.stream()
.map(OperationAuditLogEntity::getSignValue)
.collect(Collectors.toList());
@@ -232,56 +235,77 @@ public class AuditLogRestoreService {
outputStream.write(safeData);
}
- //todo后续改转义
- private List parseCsvToEntities(String[] lines) {
+
+ private List parseCsvToEntities(String csvContent) {
List 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;
}
diff --git a/src/main/java/com/cisd/tms/modules/log/service/OperationAuditService.java b/src/main/java/com/cisd/tms/modules/log/service/OperationAuditService.java
index f6be513..c491de9 100644
--- a/src/main/java/com/cisd/tms/modules/log/service/OperationAuditService.java
+++ b/src/main/java/com/cisd/tms/modules/log/service/OperationAuditService.java
@@ -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);
diff --git a/src/main/java/com/cisd/tms/modules/log/service/OperationAuditSigner.java b/src/main/java/com/cisd/tms/modules/log/service/OperationAuditSigner.java
index 7f09d0f..7c89ccc 100644
--- a/src/main/java/com/cisd/tms/modules/log/service/OperationAuditSigner.java
+++ b/src/main/java/com/cisd/tms/modules/log/service/OperationAuditSigner.java
@@ -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()));
}
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 70bdf6c..1864cb1 100644
--- a/src/main/resources/db/migration/V1__tms_schema_full.sql
+++ b/src/main/resources/db/migration/V1__tms_schema_full.sql
@@ -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`)
+)
\ No newline at end of file