From 546bf5f24042537c570642c3a8489baccea9e10a Mon Sep 17 00:00:00 2001 From: cheney Date: Fri, 15 May 2026 14:14:57 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E8=87=AA=E6=A3=80=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E8=A7=84=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/system/dto/SelfCheckResult.java | 69 +++++++++ .../system/runner/SelfCheckStartupRunner.java | 58 +++++++ .../system/service/SelfCheckService.java | 16 ++ .../service/impl/SelfCheckServiceImpl.java | 142 ++++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 src/main/java/com/cisd/tms/modules/system/dto/SelfCheckResult.java create mode 100644 src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java create mode 100644 src/main/java/com/cisd/tms/modules/system/service/SelfCheckService.java create mode 100644 src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java diff --git a/src/main/java/com/cisd/tms/modules/system/dto/SelfCheckResult.java b/src/main/java/com/cisd/tms/modules/system/dto/SelfCheckResult.java new file mode 100644 index 0000000..ec83ad0 --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/system/dto/SelfCheckResult.java @@ -0,0 +1,69 @@ +package com.cisd.tms.modules.system.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "自检结果") +public class SelfCheckResult { + + @Schema(description = "自检项目名称") + private String checkName; + + @Schema(description = "自检是否通过") + private boolean passed; + + @Schema(description = "自检详情信息") + private String message; + + @Schema(description = "自检耗时(毫秒)") + private long durationMs; + + public static SelfCheckResult success(String checkName, String message, long durationMs) { + SelfCheckResult result = new SelfCheckResult(); + result.checkName = checkName; + result.passed = true; + result.message = message; + result.durationMs = durationMs; + return result; + } + + public static SelfCheckResult failure(String checkName, String message, long durationMs) { + SelfCheckResult result = new SelfCheckResult(); + result.checkName = checkName; + result.passed = false; + result.message = message; + result.durationMs = durationMs; + return result; + } + + public String getCheckName() { + return checkName; + } + + public void setCheckName(String checkName) { + this.checkName = checkName; + } + + public boolean isPassed() { + return passed; + } + + public void setPassed(boolean passed) { + this.passed = passed; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public long getDurationMs() { + return durationMs; + } + + public void setDurationMs(long durationMs) { + this.durationMs = durationMs; + } +} \ No newline at end of file diff --git a/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java b/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java new file mode 100644 index 0000000..0bd51ea --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java @@ -0,0 +1,58 @@ +package com.cisd.tms.modules.system.runner; + +import com.cisd.tms.modules.system.dto.SelfCheckResult; +import com.cisd.tms.modules.system.service.SelfCheckService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class SelfCheckStartupRunner implements CommandLineRunner { + + private static final Logger log = LoggerFactory.getLogger(SelfCheckStartupRunner.class); + + @Autowired + private SelfCheckService selfCheckService; + + @Override + public void run(String... args) throws Exception { + log.info("══════════════════════════════════════════════════════════════"); + log.info(" 系统启动自检流程"); + log.info("══════════════════════════════════════════════════════════════"); + + try { + List results = selfCheckService.executeAllChecks(); + + boolean allPassed = results.stream().allMatch(SelfCheckResult::isPassed); + + log.info("══════════════════════════════════════════════════════════════"); + if (allPassed) { + log.info(" 自检流程全部通过"); + log.info("══════════════════════════════════════════════════════════════"); + } else { + log.error(" 自检流程存在失败项"); + log.error("══════════════════════════════════════════════════════════════"); + for (SelfCheckResult result : results) { + if (!result.isPassed()) { + log.error(" 失败项: {} - {}", result.getCheckName(), result.getMessage()); + } + } + log.warn("系统将在 10 秒后关闭..."); + try { + Thread.sleep(10000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + log.error("系统自检未通过,进程退出"); + System.exit(-9); + } + + } catch (Exception e) { + log.error("自检流程执行异常: {}", e.getMessage(), e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/cisd/tms/modules/system/service/SelfCheckService.java b/src/main/java/com/cisd/tms/modules/system/service/SelfCheckService.java new file mode 100644 index 0000000..e5e6b2a --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/system/service/SelfCheckService.java @@ -0,0 +1,16 @@ +package com.cisd.tms.modules.system.service; + +import com.cisd.tms.modules.system.dto.SelfCheckResult; + +import java.util.List; + +public interface SelfCheckService { + + SelfCheckResult verifyDeviceFingerprint(); + + SelfCheckResult verifyTmsIntegrity(); + + SelfCheckResult verifyStandardTransceiverIntegrity(); + + List executeAllChecks(); +} \ No newline at end of file diff --git a/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java b/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java new file mode 100644 index 0000000..dd38a91 --- /dev/null +++ b/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java @@ -0,0 +1,142 @@ +package com.cisd.tms.modules.system.service.impl; + +import com.cisd.tms.modules.system.dto.SelfCheckResult; +import com.cisd.tms.modules.system.service.SelfCheckService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class SelfCheckServiceImpl implements SelfCheckService { + + private static final Logger log = LoggerFactory.getLogger(SelfCheckServiceImpl.class); + + private static final String CHECK_DEVICE_FINGERPRINT = "设备指纹验证"; + private static final String CHECK_TMS_INTEGRITY = "终端管理系统主程序完整性验证"; + private static final String CHECK_STANDARD_TRANSCEIVER = "标准收发器主程序完整性验证"; + + @Override + public SelfCheckResult verifyDeviceFingerprint() { + long startTime = System.currentTimeMillis(); + log.info("========== 开始执行: {} ==========", CHECK_DEVICE_FINGERPRINT); + + try { + boolean result = doVerifyDeviceFingerprint(); + long duration = System.currentTimeMillis() - startTime; + + if (result) { + String message = "设备指纹验证通过"; + log.info("[PASS] {} - {}", CHECK_DEVICE_FINGERPRINT, message); + return SelfCheckResult.success(CHECK_DEVICE_FINGERPRINT, message, duration); + } else { + String message = "设备指纹验证失败"; + log.error("[FAIL] {} - {}", CHECK_DEVICE_FINGERPRINT, message); + return SelfCheckResult.failure(CHECK_DEVICE_FINGERPRINT, message, duration); + } + } catch (Exception e) { + long duration = System.currentTimeMillis() - startTime; + String message = "设备指纹验证异常: " + e.getMessage(); + log.error("[ERROR] {} - {}", CHECK_DEVICE_FINGERPRINT, message, e); + return SelfCheckResult.failure(CHECK_DEVICE_FINGERPRINT, message, duration); + } + } + + @Override + public SelfCheckResult verifyTmsIntegrity() { + long startTime = System.currentTimeMillis(); + log.info("========== 开始执行: {} ==========", CHECK_TMS_INTEGRITY); + + try { + boolean result = doVerifyTmsIntegrity(); + long duration = System.currentTimeMillis() - startTime; + + if (result) { + String message = "终端管理系统主程序完整性验证通过"; + log.info("[PASS] {} - {}", CHECK_TMS_INTEGRITY, message); + return SelfCheckResult.success(CHECK_TMS_INTEGRITY, message, duration); + } else { + String message = "终端管理系统主程序完整性验证失败"; + log.error("[FAIL] {} - {}", CHECK_TMS_INTEGRITY, message); + return SelfCheckResult.failure(CHECK_TMS_INTEGRITY, message, duration); + } + } catch (Exception e) { + long duration = System.currentTimeMillis() - startTime; + String message = "终端管理系统主程序完整性验证异常: " + e.getMessage(); + log.error("[ERROR] {} - {}", CHECK_TMS_INTEGRITY, message, e); + return SelfCheckResult.failure(CHECK_TMS_INTEGRITY, message, duration); + } + } + + @Override + public SelfCheckResult verifyStandardTransceiverIntegrity() { + long startTime = System.currentTimeMillis(); + log.info("========== 开始执行: {} ==========", CHECK_STANDARD_TRANSCEIVER); + + try { + boolean result = doVerifyStandardTransceiverIntegrity(); + long duration = System.currentTimeMillis() - startTime; + + if (result) { + String message = "标准收发器主程序完整性验证通过"; + log.info("[PASS] {} - {}", CHECK_STANDARD_TRANSCEIVER, message); + return SelfCheckResult.success(CHECK_STANDARD_TRANSCEIVER, message, duration); + } else { + String message = "标准收发器主程序完整性验证失败"; + log.error("[FAIL] {} - {}", CHECK_STANDARD_TRANSCEIVER, message); + return SelfCheckResult.failure(CHECK_STANDARD_TRANSCEIVER, message, duration); + } + } catch (Exception e) { + long duration = System.currentTimeMillis() - startTime; + String message = "标准收发器主程序完整性验证异常: " + e.getMessage(); + log.error("[ERROR] {} - {}", CHECK_STANDARD_TRANSCEIVER, message, e); + return SelfCheckResult.failure(CHECK_STANDARD_TRANSCEIVER, message, duration); + } + } + + @Override + public List executeAllChecks() { + log.info("======================================"); + log.info(" 系统启动自检流程开始"); + log.info("======================================"); + + long totalStartTime = System.currentTimeMillis(); + List results = new ArrayList<>(); + + results.add(verifyDeviceFingerprint()); + results.add(verifyTmsIntegrity()); + results.add(verifyStandardTransceiverIntegrity()); + + long totalDuration = System.currentTimeMillis() - totalStartTime; + long passedCount = results.stream().filter(SelfCheckResult::isPassed).count(); + long failedCount = results.size() - passedCount; + + log.info("======================================"); + log.info(" 系统启动自检流程结束"); + log.info("======================================"); + log.info("自检总耗时: {} ms", totalDuration); + log.info("检测项总数: {}, 通过: {}, 失败: {}", results.size(), passedCount, failedCount); + + if (failedCount > 0) { + log.warn("存在未通过的自检项,请检查相关日志"); + } else { + log.info("所有自检项均已通过"); + } + + return results; + } + + private boolean doVerifyDeviceFingerprint() { + return false; + } + + private boolean doVerifyTmsIntegrity() { + return false; + } + + private boolean doVerifyStandardTransceiverIntegrity() { + return false; + } +} \ No newline at end of file From cd690bd2d942b1e8e858fe7d7bf3f287de95eebb Mon Sep 17 00:00:00 2001 From: cheney Date: Fri, 15 May 2026 14:37:35 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E7=BB=88=E7=AB=AF=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=B8=BB=E7=A8=8B=E5=BA=8F=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E6=80=A7=E8=87=AA=E6=A3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device-fingerprint-tool/pom.xml | 2 +- .../com/sunyard/cisd/device/tool/Main.java | 16 +-- pom.xml | 2 +- .../service/impl/SelfCheckServiceImpl.java | 115 +++++++++++++++++- 4 files changed, 123 insertions(+), 12 deletions(-) diff --git a/device-fingerprint-tool/pom.xml b/device-fingerprint-tool/pom.xml index 76be577..546f370 100644 --- a/device-fingerprint-tool/pom.xml +++ b/device-fingerprint-tool/pom.xml @@ -6,7 +6,7 @@ com.sunyard.cisd device-fingerprint-tool - 1.0.0 + 1.0.1 device-fingerprint-tool 设备指纹信息获取工具 diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java index db27117..f22f5d5 100644 --- a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java @@ -10,24 +10,24 @@ import java.util.Map; public class Main { private static final String DEVICE_DIR = "/home/tms/device"; - private static final String SIGN_FILE = DEVICE_DIR + "/dev.sign"; + public static final String SIGN_FILE = DEVICE_DIR + "/dev.sign"; private static final String SIGN_SM3_FILE = DEVICE_DIR + "/dev.sign.sm3"; private static final String PUBLIC_KEY_FILE = DEVICE_DIR + "/dev.fingerprint.pub"; private static final String PUBLIC_KEY_SM3_FILE = DEVICE_DIR + "/dev.fingerprint.pub.sm3"; - private static final String FINGERPRINT_DATA_FILE = DEVICE_DIR + "/dev.fingerprint.data"; + public static final String FINGERPRINT_DATA_FILE = DEVICE_DIR + "/dev.fingerprint.data"; private static final String FINGERPRINT_PRIVATE_KEY_PATH = "/fingerprint_sm2_private_key.pem"; - private static final String FINGERPRINT_PUBLIC_KEY_PATH = "/fingerprint_sm2_public_key.pem"; + public static final String FINGERPRINT_PUBLIC_KEY_PATH = "/fingerprint_sm2_public_key.pem"; private static final String MAC_PRIVATE_KEY_PATH = "/mac_sm2_private_key.pem"; - private static final String MAC_PUBLIC_KEY_PATH = "/mac_sm2_public_key.pem"; + public static final String MAC_PUBLIC_KEY_PATH = "/mac_sm2_public_key.pem"; private static final String ROOT_CERT_FILE = "/CFCA_TEST_CS_SM2_CA.cer"; private static final String ROOT_CERT_OUTPUT_FILE = DEVICE_DIR + "/CFCA_TEST_CS_SM2_CA.cer"; private static final String ROOT_CERT_SIGN_FILE = DEVICE_DIR + "/rootcert.sign"; private static final String MAC_PUBLIC_KEY_OUTPUT_FILE = DEVICE_DIR + "/dev.mac.pub"; private static final String MAC_PUBLIC_KEY_SM3_FILE = DEVICE_DIR + "/dev.mac.pub.sm3"; - private static final String MAC_LIST_FILE = "/home/tms/mac.list"; - private static final String MAC_SIGN_FILE = DEVICE_DIR + "/dev.mac.sign"; + public static final String MAC_LIST_FILE = "/home/tms/mac.list"; + public static final String MAC_SIGN_FILE = DEVICE_DIR + "/dev.mac.sign"; - private static final String[] MAC_TARGETS = { + public static final String[] MAC_TARGETS = { "/home/tms/tms-framework.jar", "/home/tms/config", "/home/tms/libs", @@ -111,7 +111,7 @@ public class Main { System.out.println("硬盘序列号: " + fingerprint.getHardDiskSerialNumber()); } - private static String buildPlainText(DeviceFingerprint fingerprint) { + public static String buildPlainText(DeviceFingerprint fingerprint) { return fingerprint.getMotherboardSerialNumber() + fingerprint.getDeviceSerialNumber() + fingerprint.getCpuModel() + diff --git a/pom.xml b/pom.xml index ef7d946..3b7d717 100644 --- a/pom.xml +++ b/pom.xml @@ -119,7 +119,7 @@ com.sunyard.cisd device-fingerprint-tool - 1.0.0 + 1.0.1 diff --git a/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java b/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java index dd38a91..18c70f2 100644 --- a/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java +++ b/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java @@ -2,12 +2,22 @@ package com.cisd.tms.modules.system.service.impl; import com.cisd.tms.modules.system.dto.SelfCheckResult; import com.cisd.tms.modules.system.service.SelfCheckService; +import com.sunyard.cisd.device.tool.DeviceFingerprint; +import com.sunyard.cisd.device.tool.DeviceFingerprintService; +import com.sunyard.cisd.device.tool.SM2Util; +import com.sunyard.cisd.device.tool.SM3Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.security.PublicKey; import java.util.ArrayList; import java.util.List; +import java.util.Map; + +import static com.sunyard.cisd.device.tool.Main.*; @Service public class SelfCheckServiceImpl implements SelfCheckService { @@ -129,11 +139,112 @@ public class SelfCheckServiceImpl implements SelfCheckService { } private boolean doVerifyDeviceFingerprint() { - return false; + try { + DeviceFingerprintService service = new DeviceFingerprintService(); + DeviceFingerprint fingerprint = service.getDeviceFingerprint(); + + log.info("=== 当前设备信息 ==="); + log.info("主板序列号: " + fingerprint.getMotherboardSerialNumber()); + log.info("设备序列号: " + fingerprint.getDeviceSerialNumber()); + log.info("CPU型号: " + fingerprint.getCpuModel()); + log.info("CPU序列号: " + fingerprint.getCpuSerialNumber()); + log.info("内存大小: " + fingerprint.getMemorySize()); + log.info("首块网卡MAC地址: " + fingerprint.getFirstNetworkMacAddress()); + log.info("硬盘序列号: " + fingerprint.getHardDiskSerialNumber()); + + String plainText = buildPlainText(fingerprint); + log.info("\n当前拼接原文: " + plainText); + + String savedPlainText = SM3Util.readFile(FINGERPRINT_DATA_FILE).trim(); + log.info("保存的拼接原文: " + savedPlainText); + + byte[] signature = SM3Util.readFileBytes(SIGN_FILE); + PublicKey publicKey = SM2Util.loadPublicKey(FINGERPRINT_PUBLIC_KEY_PATH); + + boolean dataMatch = plainText.equals(savedPlainText); + boolean signatureVerified = SM2Util.verify(savedPlainText.getBytes(StandardCharsets.UTF_8), signature, publicKey); + + log.info("\n=== 验证结果 ==="); + log.info("设备信息匹配: " + dataMatch); + log.info("签名验证: " + signatureVerified); + log.info("总体验证: " + (dataMatch && signatureVerified)); + return (dataMatch && signatureVerified); + } catch (Exception e) { + log.error("[ERROR] {} - {}", CHECK_DEVICE_FINGERPRINT, e.getMessage()); + return false; + } } private boolean doVerifyTmsIntegrity() { - return false; + try { + System.out.println("=== 验证系统文件MAC校验值 ==="); + + PublicKey publicKey = SM2Util.loadPublicKey(MAC_PUBLIC_KEY_PATH); + byte[] savedSignature = SM3Util.readFileBytes(MAC_SIGN_FILE); + String savedMacList = SM3Util.readFile(MAC_LIST_FILE); + + boolean macListSignatureValid = SM2Util.verify(savedMacList.getBytes(StandardCharsets.UTF_8), savedSignature, publicKey); + System.out.println("MAC列表签名验证: " + (macListSignatureValid ? "通过" : "失败")); + + if (!macListSignatureValid) { + System.out.println("错误: mac.list 签名验证失败,可能被篡改!"); + System.out.println("\n=== 验证结果 ==="); + System.out.println("完整性验证: false"); + return false; + } + + Map savedSm3Map = SM3Util.readSM3File(MAC_LIST_FILE); + + Map currentSm3Map = new java.util.LinkedHashMap<>(); + for (String target : MAC_TARGETS) { + File file = new File(target); + if (!file.exists()) { + continue; + } + + if (file.isFile()) { + String sm3Value = SM3Util.sm3FileHex(target); + currentSm3Map.put(target, sm3Value); + } else if (file.isDirectory()) { + Map dirSm3Map = SM3Util.calculateDirectorySM3(target); + for (Map.Entry entry : dirSm3Map.entrySet()) { + String absolutePath = target + "/" + entry.getKey(); + currentSm3Map.put(absolutePath, entry.getValue()); + } + } + } + + boolean allMatch = true; + + for (Map.Entry entry : savedSm3Map.entrySet()) { + String filePath = entry.getKey(); + String savedHash = entry.getValue(); + String currentHash = currentSm3Map.get(filePath); + + if (currentHash == null) { + System.out.println("文件缺失: " + filePath); + allMatch = false; + } else if (!savedHash.equals(currentHash)) { + System.out.println("文件被修改: " + filePath + " (期望: " + savedHash + ", 实际: " + currentHash + ")"); + allMatch = false; + } + } + + for (String filePath : currentSm3Map.keySet()) { + if (!savedSm3Map.containsKey(filePath)) { + System.out.println("新增文件: " + filePath); + allMatch = false; + } + } + + System.out.println(); + System.out.println("=== 验证结果 ==="); + System.out.println("完整性验证: " + allMatch); + return allMatch; + } catch (Exception e) { + log.error("[ERROR] {} - {}", CHECK_TMS_INTEGRITY, e.getMessage()); + return false; + } } private boolean doVerifyStandardTransceiverIntegrity() { From a177277f04872b9c275fad8b33fe205a2e0ec20b Mon Sep 17 00:00:00 2001 From: cheney Date: Fri, 15 May 2026 14:46:08 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E7=BB=88=E7=AB=AF=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E4=B8=BB=E7=A8=8B=E5=BA=8F=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E6=80=A7=E8=87=AA=E6=A3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sunyard/cisd/device/tool/Main.java | 146 +++++++++++++++++- .../service/impl/SelfCheckServiceImpl.java | 86 +++++++++-- 2 files changed, 212 insertions(+), 20 deletions(-) diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java index f22f5d5..651b26a 100644 --- a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/device/tool/Main.java @@ -27,6 +27,9 @@ public class Main { public static final String MAC_LIST_FILE = "/home/tms/mac.list"; public static final String MAC_SIGN_FILE = DEVICE_DIR + "/dev.mac.sign"; + public static final String CMEP_MAC_LIST_FILE = "/home/cmep4i/cmep.mac.list"; + public static final String CMEP_MAC_SIGN_FILE = "/home/cmep4i/cmep.mac.sign"; + public static final String[] MAC_TARGETS = { "/home/tms/tms-framework.jar", "/home/tms/config", @@ -36,6 +39,11 @@ public class Main { "/home/tms/scripts/tms.sh" }; + public static final String[] CMEP_TARGETS = { + "/home/cmep4i/cmsp/CMEP-CMSP.jar", + "/home/cmep4i/cmtp/CMEP-CMSP.jar" + }; + public static void main(String[] args) { if (args.length == 0) { printHelp(); @@ -59,12 +67,18 @@ public class Main { case "fingerprint-vertify": verifyFingerprint(); break; - case "mac-gen": + case "tms-mac-gen": generateMAC(); break; - case "mac-vertify": + case "tms-mac-vertify": verifyMAC(); break; + case "cmep-mac-gen": + generateCMEPMAC(); + break; + case "cmep-mac-vertify": + verifyCMEPMAC(); + break; case "rootcert-mac-gen": generateRootCertMAC(); break; @@ -90,8 +104,10 @@ public class Main { System.out.println(" info - 获取并显示设备信息"); System.out.println(" fingerprint-gen - 获取设备信息并生成设备指纹输出到文件"); System.out.println(" fingerprint-vertify - 获取设备信息并验证设备指纹"); - System.out.println(" mac-gen - 生成系统文件MAC校验值并签名"); - System.out.println(" mac-vertify - 验证系统文件MAC校验值"); + System.out.println(" tms-mac-gen - 生成TMS系统文件MAC校验值并签名"); + System.out.println(" tms-mac-vertify - 验证TMS系统文件MAC校验值"); + System.out.println(" cmep-mac-gen - 生成CMEP文件MAC校验值并签名"); + System.out.println(" cmep-mac-vertify - 验证CMEP文件MAC校验值"); System.out.println(" rootcert-mac-gen - 生成根证书MAC签名"); System.out.println(" rootcert-mac-vertify - 验证根证书MAC签名"); System.out.println(); @@ -316,8 +332,7 @@ public class Main { throw new IllegalArgumentException("根证书文件未找到: " + ROOT_CERT_FILE); } - byte[] certData = certInputStream.readAllBytes(); - certInputStream.close(); + byte[] certData = readInputStream(certInputStream); SM3Util.writeFile(ROOT_CERT_OUTPUT_FILE, certData); System.out.println("根证书已输出: " + ROOT_CERT_OUTPUT_FILE); @@ -353,8 +368,7 @@ public class Main { if (certInputStream == null) { throw new IllegalArgumentException("根证书文件未找到: " + ROOT_CERT_FILE); } - byte[] certData = certInputStream.readAllBytes(); - certInputStream.close(); + byte[] certData = readInputStream(certInputStream); byte[] signature = SM3Util.readFileBytes(ROOT_CERT_SIGN_FILE); @@ -365,4 +379,120 @@ public class Main { System.out.println("=== 验证结果 ==="); System.out.println("总体验证: " + (publicKeyValid && signatureVerified)); } + + private static byte[] readInputStream(InputStream is) throws Exception { + try { + java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(); + byte[] buffer = new byte[8192]; + int len; + while ((len = is.read(buffer)) != -1) { + baos.write(buffer, 0, len); + } + return baos.toByteArray(); + } finally { + if (is != null) { + is.close(); + } + } + } + + private static void generateCMEPMAC() throws Exception { + System.out.println("=== 生成CMEP文件MAC校验值 ==="); + System.out.println("目标路径:"); + for (String target : CMEP_TARGETS) { + System.out.println(" " + target); + } + + Map sm3Map = new java.util.LinkedHashMap<>(); + + for (String target : CMEP_TARGETS) { + File file = new File(target); + if (!file.exists()) { + System.out.println("警告: 路径不存在 - " + target); + continue; + } + + if (file.isFile()) { + String sm3Value = SM3Util.sm3FileHex(target); + sm3Map.put(target, sm3Value); + System.out.println("文件: " + target + " -> " + sm3Value); + } + } + + StringBuilder macListContent = new StringBuilder(); + for (Map.Entry entry : sm3Map.entrySet()) { + macListContent.append(entry.getKey()).append("|").append(entry.getValue()).append("\n"); + } + + SM3Util.writeFile(CMEP_MAC_LIST_FILE, macListContent.toString()); + System.out.println("\nCMEP MAC列表文件已保存: " + CMEP_MAC_LIST_FILE); + + byte[] signature = SM2Util.sign(macListContent.toString().getBytes(StandardCharsets.UTF_8), MAC_PRIVATE_KEY_PATH); + SM3Util.writeFile(CMEP_MAC_SIGN_FILE, signature); + System.out.println("CMEP MAC签名文件已保存: " + CMEP_MAC_SIGN_FILE); + + PublicKey publicKey = SM2Util.loadPublicKey(MAC_PUBLIC_KEY_PATH); + boolean verified = SM2Util.verify(macListContent.toString().getBytes(StandardCharsets.UTF_8), signature, publicKey); + System.out.println("\n签名验证结果: " + verified); + } + + private static void verifyCMEPMAC() throws Exception { + System.out.println("=== 验证CMEP文件MAC校验值 ==="); + + PublicKey publicKey = SM2Util.loadPublicKey(MAC_PUBLIC_KEY_PATH); + byte[] savedSignature = SM3Util.readFileBytes(CMEP_MAC_SIGN_FILE); + String savedMacList = SM3Util.readFile(CMEP_MAC_LIST_FILE); + + boolean macListSignatureValid = SM2Util.verify(savedMacList.getBytes(StandardCharsets.UTF_8), savedSignature, publicKey); + System.out.println("CMEP MAC列表签名验证: " + (macListSignatureValid ? "通过" : "失败")); + + if (!macListSignatureValid) { + System.out.println("错误: cmep.mac.list 签名验证失败,可能被篡改!"); + System.out.println("\n=== 验证结果 ==="); + System.out.println("完整性验证: false"); + return; + } + + Map savedSm3Map = SM3Util.readSM3File(CMEP_MAC_LIST_FILE); + + Map currentSm3Map = new java.util.LinkedHashMap<>(); + for (String target : CMEP_TARGETS) { + File file = new File(target); + if (!file.exists()) { + continue; + } + + if (file.isFile()) { + String sm3Value = SM3Util.sm3FileHex(target); + currentSm3Map.put(target, sm3Value); + } + } + + boolean allMatch = true; + + for (Map.Entry entry : savedSm3Map.entrySet()) { + String filePath = entry.getKey(); + String savedHash = entry.getValue(); + String currentHash = currentSm3Map.get(filePath); + + if (currentHash == null) { + System.out.println("文件缺失: " + filePath); + allMatch = false; + } else if (!savedHash.equals(currentHash)) { + System.out.println("文件被修改: " + filePath + " (期望: " + savedHash + ", 实际: " + currentHash + ")"); + allMatch = false; + } + } + + for (String filePath : currentSm3Map.keySet()) { + if (!savedSm3Map.containsKey(filePath)) { + System.out.println("新增文件: " + filePath); + allMatch = false; + } + } + + System.out.println(); + System.out.println("=== 验证结果 ==="); + System.out.println("完整性验证: " + allMatch); + } } diff --git a/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java b/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java index 18c70f2..17b86ab 100644 --- a/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java +++ b/src/main/java/com/cisd/tms/modules/system/service/impl/SelfCheckServiceImpl.java @@ -177,19 +177,19 @@ public class SelfCheckServiceImpl implements SelfCheckService { private boolean doVerifyTmsIntegrity() { try { - System.out.println("=== 验证系统文件MAC校验值 ==="); + log.info("=== 验证系统文件MAC校验值 ==="); PublicKey publicKey = SM2Util.loadPublicKey(MAC_PUBLIC_KEY_PATH); byte[] savedSignature = SM3Util.readFileBytes(MAC_SIGN_FILE); String savedMacList = SM3Util.readFile(MAC_LIST_FILE); boolean macListSignatureValid = SM2Util.verify(savedMacList.getBytes(StandardCharsets.UTF_8), savedSignature, publicKey); - System.out.println("MAC列表签名验证: " + (macListSignatureValid ? "通过" : "失败")); + log.info("MAC列表签名验证: " + (macListSignatureValid ? "通过" : "失败")); if (!macListSignatureValid) { - System.out.println("错误: mac.list 签名验证失败,可能被篡改!"); - System.out.println("\n=== 验证结果 ==="); - System.out.println("完整性验证: false"); + log.info("错误: mac.list 签名验证失败,可能被篡改!"); + log.info("\n=== 验证结果 ==="); + log.info("完整性验证: false"); return false; } @@ -222,24 +222,24 @@ public class SelfCheckServiceImpl implements SelfCheckService { String currentHash = currentSm3Map.get(filePath); if (currentHash == null) { - System.out.println("文件缺失: " + filePath); + log.info("文件缺失: " + filePath); allMatch = false; } else if (!savedHash.equals(currentHash)) { - System.out.println("文件被修改: " + filePath + " (期望: " + savedHash + ", 实际: " + currentHash + ")"); + log.info("文件被修改: " + filePath + " (期望: " + savedHash + ", 实际: " + currentHash + ")"); allMatch = false; } } for (String filePath : currentSm3Map.keySet()) { if (!savedSm3Map.containsKey(filePath)) { - System.out.println("新增文件: " + filePath); + log.info("新增文件: " + filePath); allMatch = false; } } - System.out.println(); - System.out.println("=== 验证结果 ==="); - System.out.println("完整性验证: " + allMatch); + log.info(""); + log.info("=== 验证结果 ==="); + log.info("完整性验证: " + allMatch); return allMatch; } catch (Exception e) { log.error("[ERROR] {} - {}", CHECK_TMS_INTEGRITY, e.getMessage()); @@ -248,6 +248,68 @@ public class SelfCheckServiceImpl implements SelfCheckService { } private boolean doVerifyStandardTransceiverIntegrity() { - return false; + try { + log.info("=== 验证CMEP文件MAC校验值 ==="); + + PublicKey publicKey = SM2Util.loadPublicKey(MAC_PUBLIC_KEY_PATH); + byte[] savedSignature = SM3Util.readFileBytes(CMEP_MAC_SIGN_FILE); + String savedMacList = SM3Util.readFile(CMEP_MAC_LIST_FILE); + + boolean macListSignatureValid = SM2Util.verify(savedMacList.getBytes(StandardCharsets.UTF_8), savedSignature, publicKey); + log.info("CMEP MAC列表签名验证: " + (macListSignatureValid ? "通过" : "失败")); + + if (!macListSignatureValid) { + log.info("错误: cmep.mac.list 签名验证失败,可能被篡改!"); + log.info("\n=== 验证结果 ==="); + log.info("完整性验证: false"); + return false; + } + + Map savedSm3Map = SM3Util.readSM3File(CMEP_MAC_LIST_FILE); + + Map currentSm3Map = new java.util.LinkedHashMap<>(); + for (String target : CMEP_TARGETS) { + File file = new File(target); + if (!file.exists()) { + continue; + } + + if (file.isFile()) { + String sm3Value = SM3Util.sm3FileHex(target); + currentSm3Map.put(target, sm3Value); + } + } + + boolean allMatch = true; + + for (Map.Entry entry : savedSm3Map.entrySet()) { + String filePath = entry.getKey(); + String savedHash = entry.getValue(); + String currentHash = currentSm3Map.get(filePath); + + if (currentHash == null) { + log.info("文件缺失: " + filePath); + allMatch = false; + } else if (!savedHash.equals(currentHash)) { + log.info("文件被修改: " + filePath + " (期望: " + savedHash + ", 实际: " + currentHash + ")"); + allMatch = false; + } + } + + for (String filePath : currentSm3Map.keySet()) { + if (!savedSm3Map.containsKey(filePath)) { + log.info("新增文件: " + filePath); + allMatch = false; + } + } + + log.info(""); + log.info("=== 验证结果 ==="); + log.info("完整性验证: " + allMatch); + return allMatch; + } catch (Exception e) { + log.error("[ERROR] {} - {}", CHECK_STANDARD_TRANSCEIVER, e.getMessage()); + return false; + } } } \ No newline at end of file From 37337526c3156227745b38a653c43f1a5c1a4599 Mon Sep 17 00:00:00 2001 From: cheney Date: Fri, 15 May 2026 15:05:09 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E6=A3=80?= =?UTF-8?q?=E8=B7=B3=E8=BF=87=E6=9C=BA=E5=88=B6:TMS=5FSELFCHECK=5FSKIP=3Dt?= =?UTF-8?q?rue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/system/runner/SelfCheckStartupRunner.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java b/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java index 0bd51ea..37e9d34 100644 --- a/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java +++ b/src/main/java/com/cisd/tms/modules/system/runner/SelfCheckStartupRunner.java @@ -18,12 +18,21 @@ public class SelfCheckStartupRunner implements CommandLineRunner { @Autowired private SelfCheckService selfCheckService; + private static final String SELFCHECK_SKIP_ENV = "TMS_SELFCHECK_SKIP"; + @Override public void run(String... args) throws Exception { log.info("══════════════════════════════════════════════════════════════"); log.info(" 系统启动自检流程"); log.info("══════════════════════════════════════════════════════════════"); + String skipSelfCheck = System.getenv(SELFCHECK_SKIP_ENV); + if ("true".equalsIgnoreCase(skipSelfCheck)) { + log.warn("检测到环境变量 {}=true,跳过自检流程", SELFCHECK_SKIP_ENV); + log.info("══════════════════════════════════════════════════════════════"); + return; + } + try { List results = selfCheckService.executeAllChecks();