From 3779a055e07b957f27676fe1dc2202daf39ceab8 Mon Sep 17 00:00:00 2001 From: cheney Date: Wed, 13 May 2026 15:01:28 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=96=E5=86=99=E8=AE=BE=E5=A4=87=E6=8C=87?= =?UTF-8?q?=E7=BA=B9=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device-activation-platform/Readme.md | 2 - device-fingerprint-tool/pom.xml | 49 +++++++ .../com/sunyard/cisd/DeviceFingerprint.java | 83 +++++++++++ .../cisd/DeviceFingerprintService.java | 135 ++++++++++++++++++ .../src/main/java/com/sunyard/cisd/Main.java | 11 ++ .../main/java/com/sunyard/cisd/SDFNative.java | 25 ++++ .../java/com/sunyard/cisd/SdfDeviceInfo.java | 41 ++++++ 7 files changed, 344 insertions(+), 2 deletions(-) create mode 100644 device-fingerprint-tool/pom.xml create mode 100644 device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprint.java create mode 100644 device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprintService.java create mode 100644 device-fingerprint-tool/src/main/java/com/sunyard/cisd/SDFNative.java create mode 100644 device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfDeviceInfo.java diff --git a/device-activation-platform/Readme.md b/device-activation-platform/Readme.md index 7425d4f..a5b53af 100644 --- a/device-activation-platform/Readme.md +++ b/device-activation-platform/Readme.md @@ -57,8 +57,6 @@ 内存大小 首块网卡MAC地址 硬盘序列号 - 起始日期 - 终止日期 } 设备指纹是设备指纹信息的 SM2 签名(pkcs1 格式)。 diff --git a/device-fingerprint-tool/pom.xml b/device-fingerprint-tool/pom.xml new file mode 100644 index 0000000..efc978d --- /dev/null +++ b/device-fingerprint-tool/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + com.sunyard.cisd + device-fingerprint-tool + 1.0.0 + device-fingerprint-tool + 设备指纹信息获取工具 + + + 1.8 + 1.8 + 1.8 + UTF-8 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + true + com.sunyard.cisd.Main + + + + + + + \ No newline at end of file diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprint.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprint.java new file mode 100644 index 0000000..0075555 --- /dev/null +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprint.java @@ -0,0 +1,83 @@ +package com.sunyard.cisd; + +public class DeviceFingerprint { + private String motherboardSerialNumber; + private String deviceSerialNumber; + private String cpuModel; + private String cpuSerialNumber; + private String memorySize; + private String firstNetworkMacAddress; + private String hardDiskSerialNumber; + + public DeviceFingerprint() { + } + + public String getMotherboardSerialNumber() { + return motherboardSerialNumber; + } + + public void setMotherboardSerialNumber(String motherboardSerialNumber) { + this.motherboardSerialNumber = motherboardSerialNumber; + } + + public String getDeviceSerialNumber() { + return deviceSerialNumber; + } + + public void setDeviceSerialNumber(String deviceSerialNumber) { + this.deviceSerialNumber = deviceSerialNumber; + } + + public String getCpuModel() { + return cpuModel; + } + + public void setCpuModel(String cpuModel) { + this.cpuModel = cpuModel; + } + + public String getCpuSerialNumber() { + return cpuSerialNumber; + } + + public void setCpuSerialNumber(String cpuSerialNumber) { + this.cpuSerialNumber = cpuSerialNumber; + } + + public String getMemorySize() { + return memorySize; + } + + public void setMemorySize(String memorySize) { + this.memorySize = memorySize; + } + + public String getFirstNetworkMacAddress() { + return firstNetworkMacAddress; + } + + public void setFirstNetworkMacAddress(String firstNetworkMacAddress) { + this.firstNetworkMacAddress = firstNetworkMacAddress; + } + + public String getHardDiskSerialNumber() { + return hardDiskSerialNumber; + } + + public void setHardDiskSerialNumber(String hardDiskSerialNumber) { + this.hardDiskSerialNumber = hardDiskSerialNumber; + } + + @Override + public String toString() { + return "DeviceFingerprint{" + + "motherboardSerialNumber='" + motherboardSerialNumber + '\'' + + ", deviceSerialNumber='" + deviceSerialNumber + '\'' + + ", cpuModel='" + cpuModel + '\'' + + ", cpuSerialNumber='" + cpuSerialNumber + '\'' + + ", memorySize='" + memorySize + '\'' + + ", firstNetworkMacAddress='" + firstNetworkMacAddress + '\'' + + ", hardDiskSerialNumber='" + hardDiskSerialNumber + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprintService.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprintService.java new file mode 100644 index 0000000..e451fde --- /dev/null +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprintService.java @@ -0,0 +1,135 @@ +package com.sunyard.cisd; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class DeviceFingerprintService { + + public DeviceFingerprint getDeviceFingerprint() { + DeviceFingerprint fingerprint = new DeviceFingerprint(); + + String cpuSerialNumber = getCpuSerialNumber(); + fingerprint.setCpuSerialNumber(cpuSerialNumber); + fingerprint.setMotherboardSerialNumber(cpuSerialNumber); + + fingerprint.setCpuModel(getCpuModel()); + fingerprint.setMemorySize(getMemorySize()); + fingerprint.setFirstNetworkMacAddress(getFirstNetworkMacAddress()); + fingerprint.setHardDiskSerialNumber(getHardDiskSerialNumber()); + fingerprint.setDeviceSerialNumber(getDeviceSerialNumber()); + + return fingerprint; + } + + private String getCpuModel() { + return executeCommand("dmidecode -t processor | grep \"Version\" | awk -F\\ '{print $2$3$4}'"); + } + + private String getCpuSerialNumber() { + return executeCommand("dmidecode -t processor | grep \"Serial Number\" | awk -F\\ '{print $3}'"); + } + + private String getHardDiskSerialNumber() { + return executeCommand("lsblk -o SERIAL /dev/sda | awk 'NR==2{print $1}'"); + } + + private String getMemorySize() { + String result = executeCommand("free -h | grep Mem | awk '{print $2}'"); + return result != null && !result.isEmpty() ? result : "Unknown"; + } + + private String getFirstNetworkMacAddress() { + String result = executeCommand("ip link show | awk '/ether/ {print $2; exit}'"); + return result != null && !result.isEmpty() ? result : "Unknown"; + } + + private String getDeviceSerialNumber() { + if (!SDFNative.isLibraryLoaded()) { + return "Unknown"; + } + + int hDevice = -1; + int hSession = -1; + + try { + byte[] deviceName = new byte[256]; + int[] deviceNameLen = new int[]{256}; + int ret = SDFNative.SDF_OpenDevice(0, deviceName, deviceNameLen); + if (ret != 0) { + System.err.println("SDF_OpenDevice failed with error: " + ret); + return "Unknown"; + } + hDevice = ret; + + byte[] appID = "DeviceFingerprint".getBytes(); + int[] sessionHandle = new int[1]; + ret = SDFNative.SDF_OpenSession(hDevice, 0, appID, appID.length, sessionHandle); + if (ret != 0) { + System.err.println("SDF_OpenSession failed with error: " + ret); + return "Unknown"; + } + hSession = sessionHandle[0]; + + SdfDeviceInfo info = new SdfDeviceInfo(); + ret = SDFNative.SDF_GetDeviceInfo(hSession, info); + if (ret != 0) { + System.err.println("SDF_GetDeviceInfo failed with error: " + ret); + return "Unknown"; + } + info.read(); + + String deviceSerial = info.getDeviceSerial(); + return deviceSerial.isEmpty() ? "Unknown" : deviceSerial; + + } catch (UnsatisfiedLinkError | Exception e) { + System.err.println("Failed to get device serial number from SDF: " + e.getMessage()); + return "Unknown"; + } finally { + if (hSession != -1) { + try { + SDFNative.SDF_CloseSession(hSession); + } catch (Exception e) { + System.err.println("Error closing session: " + e.getMessage()); + } + } + if (hDevice != -1) { + try { + SDFNative.SDF_CloseDevice(hDevice); + } catch (Exception e) { + System.err.println("Error closing device: " + e.getMessage()); + } + } + } + } + + private String executeCommand(String command) { + try { + Process process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", command}); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + + String line; + StringBuilder output = new StringBuilder(); + while ((line = reader.readLine()) != null) { + output.append(line); + } + + String errorOutput = ""; + while ((line = errorReader.readLine()) != null) { + errorOutput += line; + } + + int exitCode = process.waitFor(); + if (exitCode == 0) { + String result = output.toString().trim(); + return result.isEmpty() ? "Unknown" : result; + } else { + System.err.println("Command '" + command + "' failed with exit code " + exitCode + ": " + errorOutput); + return "Unknown"; + } + } catch (Exception e) { + System.err.println("Error executing command '" + command + "': " + e.getMessage()); + return "Unknown"; + } + } +} \ No newline at end of file diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/Main.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/Main.java index a5d0b70..39d89cb 100644 --- a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/Main.java +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/Main.java @@ -2,5 +2,16 @@ package com.sunyard.cisd; public class Main { public static void main(String[] args) { + DeviceFingerprintService service = new DeviceFingerprintService(); + DeviceFingerprint fingerprint = service.getDeviceFingerprint(); + + System.out.println("=== 设备指纹信息 ==="); + System.out.println("主板序列号: " + fingerprint.getMotherboardSerialNumber()); + System.out.println("设备序列号: " + fingerprint.getDeviceSerialNumber()); + System.out.println("CPU型号: " + fingerprint.getCpuModel()); + System.out.println("CPU序列号: " + fingerprint.getCpuSerialNumber()); + System.out.println("内存大小: " + fingerprint.getMemorySize()); + System.out.println("首块网卡MAC地址: " + fingerprint.getFirstNetworkMacAddress()); + System.out.println("硬盘序列号: " + fingerprint.getHardDiskSerialNumber()); } } \ No newline at end of file diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SDFNative.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SDFNative.java new file mode 100644 index 0000000..9eb59f4 --- /dev/null +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SDFNative.java @@ -0,0 +1,25 @@ +package com.sunyard.cisd; + +public class SDFNative { + private static final String SDF_LIBRARY_PATH = "/home/tms/libs/libsdf_syd1408-x64.so.1.0.0"; + private static boolean libraryLoaded = false; + + static { + try { + System.load(SDF_LIBRARY_PATH); + libraryLoaded = true; + } catch (UnsatisfiedLinkError e) { + System.err.println("Warning: SDF library not loaded: " + e.getMessage()); + } + } + + public static boolean isLibraryLoaded() { + return libraryLoaded; + } + + public static native int SDF_OpenDevice(int dwDeviceType, byte[] pDeviceName, int[] pdwDeviceNameLen); + public static native int SDF_CloseDevice(int hDevice); + public static native int SDF_OpenSession(int hDevice, int dwAppType, byte[] pAppID, int dwAppIDLen, int[] phSession); + public static native int SDF_CloseSession(int hSession); + public static native int SDF_GetDeviceInfo(int hSession, SdfDeviceInfo pDeviceInfo); +} \ No newline at end of file diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfDeviceInfo.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfDeviceInfo.java new file mode 100644 index 0000000..af8b64d --- /dev/null +++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfDeviceInfo.java @@ -0,0 +1,41 @@ +package com.sunyard.cisd; + +import java.nio.ByteBuffer; + +public class SdfDeviceInfo { + public byte[] issuerName = new byte[40]; + public byte[] deviceName = new byte[40]; + public byte[] deviceSerial = new byte[40]; + public int deviceVersion; + public int standardVersion; + public int asymAlgAbility[] = new int[2]; + public int symAlgAbility; + public int hashAlgAbility; + public int bufferSize; + + public void read() { + } + + public String getIssuerName() { + return zeroTerminatedString(issuerName); + } + + public String getDeviceName() { + return zeroTerminatedString(deviceName); + } + + public String getDeviceSerial() { + return zeroTerminatedString(deviceSerial); + } + + private String zeroTerminatedString(byte[] bytes) { + if (bytes == null || bytes.length == 0) { + return ""; + } + int len = 0; + while (len < bytes.length && bytes[len] != 0) { + len++; + } + return new String(bytes, 0, len).trim(); + } +} \ No newline at end of file