diff --git a/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationController.java b/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationController.java
index 69571c2..f8e7626 100644
--- a/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationController.java
+++ b/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationController.java
@@ -6,6 +6,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.security.KeyPair;
+import java.util.Base64;
+
@RestController
@RequestMapping("/device")
public class DeviceActivationController {
@@ -24,8 +27,10 @@ public class DeviceActivationController {
String concatenatedParams = params.toConcatenatedString();
String calculatedHash = deviceActivationService.calculateSm3Hash(concatenatedParams);
- String deviceActivationPublicKey = deviceActivationService.generateDeviceActivationPublicKey();
- String deviceActivationResult = deviceActivationService.signWithSm2Pkcs1(calculatedHash, deviceActivationPublicKey);
+ KeyPair keyPair = deviceActivationService.generateDeviceActivationKeyPair();
+ String deviceActivationPublicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
+ String privateKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
+ String deviceActivationResult = deviceActivationService.signWithSm2Pkcs1(calculatedHash, privateKeyBase64);
DeviceActivationResponse.Data data = new DeviceActivationResponse.Data();
data.setHash(calculatedHash);
diff --git a/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationService.java b/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationService.java
index ca76d4a..03563ef 100644
--- a/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationService.java
+++ b/device-activation-platform/src/main/java/com/sunyar/cisd/DeviceActivationService.java
@@ -63,6 +63,16 @@ public class DeviceActivationService {
}
}
+ public KeyPair generateDeviceActivationKeyPair() {
+ try {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", PROVIDER);
+ keyGen.initialize(256);
+ return keyGen.generateKeyPair();
+ } catch (Exception e) {
+ throw new RuntimeException("生成设备激活密钥对失败", e);
+ }
+ }
+
public KeyPair generateKeyPair() {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", PROVIDER);
diff --git a/device-fingerprint-tool/pom.xml b/device-fingerprint-tool/pom.xml
index efc978d..0f6ee98 100644
--- a/device-fingerprint-tool/pom.xml
+++ b/device-fingerprint-tool/pom.xml
@@ -18,6 +18,33 @@
+
+ net.java.dev.jna
+ jna
+ 5.9.0
+
+
+ net.java.dev.jna
+ jna-platform
+ 5.9.0
+
+
+ org.projectlombok
+ lombok
+ 1.18.42
+ provided
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.70
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
@@ -44,6 +71,30 @@
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.3.0
+
+
+ jar-with-dependencies
+
+
+
+ com.sunyard.cisd.Main
+
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
\ 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
index e451fde..1afa471 100644
--- a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprintService.java
+++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/DeviceFingerprintService.java
@@ -1,9 +1,45 @@
package com.sunyard.cisd;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.PointerByReference;
import java.io.BufferedReader;
+import java.io.File;
import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
public class DeviceFingerprintService {
+ private static final String SDF_LIBRARY_PATH = "/home/tms/libs/libsdf_syd1408-x64.so.1.0.0";
+ private static SdfNativeLibrary sdfLibrary = null;
+ private static boolean libraryLoaded = false;
+ private static String loadError = null;
+
+ static {
+ System.out.println("[DEBUG] Attempting to load SDF library from: " + SDF_LIBRARY_PATH);
+
+ File libFile = new File(SDF_LIBRARY_PATH);
+ if (libFile.exists()) {
+ System.out.println("[DEBUG] Library file exists: " + SDF_LIBRARY_PATH);
+ System.out.println("[DEBUG] File size: " + libFile.length() + " bytes");
+ } else {
+ System.out.println("[ERROR] Library file not found: " + SDF_LIBRARY_PATH);
+ loadError = "Library file not found";
+ }
+
+ try {
+ sdfLibrary = Native.load(SDF_LIBRARY_PATH, SdfNativeLibrary.class);
+ libraryLoaded = true;
+ System.out.println("[DEBUG] SDF library loaded successfully");
+ } catch (UnsatisfiedLinkError e) {
+ loadError = "UnsatisfiedLinkError: " + e.getMessage();
+ System.err.println("[ERROR] Failed to load SDF library (UnsatisfiedLinkError): " + e.getMessage());
+ System.err.println("[ERROR] Cause: " + (e.getCause() != null ? e.getCause().getMessage() : "null"));
+ } catch (Exception e) {
+ loadError = "Exception: " + e.getMessage();
+ System.err.println("[ERROR] Failed to load SDF library (Exception): " + e.getClass().getName() + " - " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
public DeviceFingerprint getDeviceFingerprint() {
DeviceFingerprint fingerprint = new DeviceFingerprint();
@@ -43,65 +79,148 @@ public class DeviceFingerprintService {
return result != null && !result.isEmpty() ? result : "Unknown";
}
+ private static String zeroTerminatedString(byte[] value) {
+ int len = 0;
+ while (len < value.length && value[len] != 0) {
+ len++;
+ }
+ return new String(value, 0, len, StandardCharsets.UTF_8).trim();
+ }
+
private String getDeviceSerialNumber() {
- if (!SDFNative.isLibraryLoaded()) {
+ System.out.println("[DEBUG] getDeviceSerialNumber() called");
+ System.out.println("[DEBUG] Library loaded: " + libraryLoaded + ", sdfLibrary: " + (sdfLibrary != null ? "not null" : "null"));
+
+ if (!libraryLoaded || sdfLibrary == null) {
+ System.err.println("[ERROR] SDF library not loaded. Cannot get device serial number.");
+ System.err.println("[ERROR] Load error: " + loadError);
return "Unknown";
}
- int hDevice = -1;
- int hSession = -1;
+ Pointer deviceHandle = null;
+ Pointer sessionHandle = null;
try {
- byte[] deviceName = new byte[256];
- int[] deviceNameLen = new int[]{256};
- int ret = SDFNative.SDF_OpenDevice(0, deviceName, deviceNameLen);
+ System.out.println("[DEBUG] Calling SDF_OpenDevice...");
+ PointerByReference phDeviceHandle = new PointerByReference();
+ int ret = sdfLibrary.SDF_OpenDevice(phDeviceHandle);
+ System.out.println("[DEBUG] SDF_OpenDevice returned: " + ret);
+
if (ret != 0) {
- System.err.println("SDF_OpenDevice failed with error: " + ret);
+ System.err.println("[ERROR] SDF_OpenDevice failed with error code: " + ret);
+ System.err.println("[ERROR] Error code meaning: " + getErrorMessage(ret));
return "Unknown";
}
- hDevice = ret;
+ deviceHandle = phDeviceHandle.getValue();
+ System.out.println("[DEBUG] Device handle obtained: " + deviceHandle);
- byte[] appID = "DeviceFingerprint".getBytes();
- int[] sessionHandle = new int[1];
- ret = SDFNative.SDF_OpenSession(hDevice, 0, appID, appID.length, sessionHandle);
+ System.out.println("[DEBUG] Calling SDF_OpenSession...");
+ PointerByReference phSessionHandle = new PointerByReference();
+ ret = sdfLibrary.SDF_OpenSession(deviceHandle, phSessionHandle);
+ System.out.println("[DEBUG] SDF_OpenSession returned: " + ret);
+
if (ret != 0) {
- System.err.println("SDF_OpenSession failed with error: " + ret);
+ System.err.println("[ERROR] SDF_OpenSession failed with error code: " + ret);
+ System.err.println("[ERROR] Error code meaning: " + getErrorMessage(ret));
return "Unknown";
}
- hSession = sessionHandle[0];
+ sessionHandle = phSessionHandle.getValue();
+ System.out.println("[DEBUG] Session handle obtained: " + sessionHandle);
+ System.out.println("[DEBUG] Calling SDF_GetDeviceInfo...");
SdfDeviceInfo info = new SdfDeviceInfo();
- ret = SDFNative.SDF_GetDeviceInfo(hSession, info);
+ ret = sdfLibrary.SDF_GetDeviceInfo(sessionHandle, info);
+ System.out.println("[DEBUG] SDF_GetDeviceInfo returned: " + ret);
+
if (ret != 0) {
- System.err.println("SDF_GetDeviceInfo failed with error: " + ret);
+ System.err.println("[ERROR] SDF_GetDeviceInfo failed with error code: " + ret);
+ System.err.println("[ERROR] Error code meaning: " + getErrorMessage(ret));
return "Unknown";
}
- info.read();
- String deviceSerial = info.getDeviceSerial();
- return deviceSerial.isEmpty() ? "Unknown" : deviceSerial;
+ String issuerName = zeroTerminatedString(info.getIssuerName());
+ String deviceName = zeroTerminatedString(info.getDeviceName());
+ String deviceSerial = zeroTerminatedString(info.getDeviceSerial());
+
+ System.out.println("[DEBUG] Device info retrieved:");
+ System.out.println("[DEBUG] IssuerName: '" + issuerName + "'");
+ System.out.println("[DEBUG] DeviceName: '" + deviceName + "'");
+ System.out.println("[DEBUG] DeviceSerial: '" + deviceSerial + "'");
- } catch (UnsatisfiedLinkError | Exception e) {
- System.err.println("Failed to get device serial number from SDF: " + e.getMessage());
+ if (deviceSerial == null || deviceSerial.isEmpty()) {
+ System.err.println("[WARNING] Device serial number is empty");
+ return "Unknown";
+ }
+
+ return deviceSerial;
+
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("[ERROR] UnsatisfiedLinkError when calling SDF API: " + e.getMessage());
+ e.printStackTrace();
+ return "Unknown";
+ } catch (Exception e) {
+ System.err.println("[ERROR] Exception when calling SDF API: " + e.getClass().getName() + " - " + e.getMessage());
+ e.printStackTrace();
return "Unknown";
} finally {
- if (hSession != -1) {
+ if (sessionHandle != null) {
try {
- SDFNative.SDF_CloseSession(hSession);
+ System.out.println("[DEBUG] Closing session handle: " + sessionHandle);
+ sdfLibrary.SDF_CloseSession(sessionHandle);
} catch (Exception e) {
- System.err.println("Error closing session: " + e.getMessage());
+ System.err.println("[ERROR] Error closing session: " + e.getMessage());
}
}
- if (hDevice != -1) {
+ if (deviceHandle != null) {
try {
- SDFNative.SDF_CloseDevice(hDevice);
+ System.out.println("[DEBUG] Closing device handle: " + deviceHandle);
+ sdfLibrary.SDF_CloseDevice(deviceHandle);
} catch (Exception e) {
- System.err.println("Error closing device: " + e.getMessage());
+ System.err.println("[ERROR] Error closing device: " + e.getMessage());
}
}
}
}
+ private String getErrorMessage(int errorCode) {
+ switch (errorCode) {
+ case 0:
+ return "Success";
+ case -1:
+ return "General error";
+ case -2:
+ return "Invalid parameter";
+ case -3:
+ return "Memory allocation failed";
+ case -4:
+ return "Device not found";
+ case -5:
+ return "Device not opened";
+ case -6:
+ return "Session not opened";
+ case -7:
+ return "Operation not supported";
+ case -8:
+ return "Key not found";
+ case -9:
+ return "Key access denied";
+ case -10:
+ return "Invalid key";
+ case -11:
+ return "Invalid signature";
+ case -12:
+ return "Invalid certificate";
+ case -13:
+ return "Buffer too small";
+ case -14:
+ return "Timeout";
+ case -15:
+ return "Hardware error";
+ default:
+ return "Unknown error code: " + errorCode;
+ }
+ }
+
private String executeCommand(String command) {
try {
Process process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", command});
@@ -124,11 +243,11 @@ public class DeviceFingerprintService {
String result = output.toString().trim();
return result.isEmpty() ? "Unknown" : result;
} else {
- System.err.println("Command '" + command + "' failed with exit code " + exitCode + ": " + errorOutput);
+ System.err.println("[ERROR] Command '" + command + "' failed with exit code " + exitCode + ": " + errorOutput);
return "Unknown";
}
} catch (Exception e) {
- System.err.println("Error executing command '" + command + "': " + e.getMessage());
+ System.err.println("[ERROR] Error executing command '" + command + "': " + e.getMessage());
return "Unknown";
}
}
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
deleted file mode 100644
index 9eb59f4..0000000
--- a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SDFNative.java
+++ /dev/null
@@ -1,25 +0,0 @@
-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/SM2Util.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SM2Util.java
new file mode 100644
index 0000000..0b86562
--- /dev/null
+++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SM2Util.java
@@ -0,0 +1,156 @@
+package com.sunyard.cisd;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.engines.SM2Engine;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.crypto.signers.SM2Signer;
+import org.bouncycastle.jce.ECNamedCurveTable;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECParameterSpec;
+import org.bouncycastle.jce.spec.ECPrivateKeySpec;
+import org.bouncycastle.jce.spec.ECPublicKeySpec;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.BigIntegers;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+public class SM2Util {
+ private static final String ALGORITHM = "EC";
+ private static final String PROVIDER = "BC";
+ private static final String CURVE_NAME = "sm2p256v1";
+ private static final String SIGNATURE_ALGORITHM = "SM3withSM2";
+
+ static {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public static byte[] sign(byte[] data, PrivateKey privateKey) throws Exception {
+ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
+ signature.initSign(privateKey);
+ signature.update(data);
+ return signature.sign();
+ }
+
+ public static boolean verify(byte[] data, byte[] sign, PublicKey publicKey) throws Exception {
+ Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
+ signature.initVerify(publicKey);
+ signature.update(data);
+ return signature.verify(sign);
+ }
+
+ public static byte[] sign(byte[] data, String privateKeyFilePath) throws Exception {
+ PrivateKey privateKey = loadPrivateKey(privateKeyFilePath);
+ return sign(data, privateKey);
+ }
+
+ public static boolean verify(byte[] data, byte[] sign, String publicKeyFilePath) throws Exception {
+ PublicKey publicKey = loadPublicKey(publicKeyFilePath);
+ return verify(data, sign, publicKey);
+ }
+
+ public static PrivateKey loadPrivateKey(String filePath) throws Exception {
+ InputStream inputStream = SM2Util.class.getResourceAsStream(filePath);
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Private key file not found: " + filePath);
+ }
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+ StringBuilder keyBuilder = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (!line.startsWith("-----")) {
+ keyBuilder.append(line.trim());
+ }
+ }
+ reader.close();
+
+ String keyBase64 = keyBuilder.toString();
+ byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
+
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
+ return keyFactory.generatePrivate(keySpec);
+ }
+
+ public static PublicKey loadPublicKey(String filePath) throws Exception {
+ InputStream inputStream = SM2Util.class.getResourceAsStream(filePath);
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Public key file not found: " + filePath);
+ }
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+ StringBuilder keyBuilder = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (!line.startsWith("-----")) {
+ keyBuilder.append(line.trim());
+ }
+ }
+ reader.close();
+
+ String keyBase64 = keyBuilder.toString();
+ byte[] keyBytes = Base64.getDecoder().decode(keyBase64);
+
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM, PROVIDER);
+ return keyFactory.generatePublic(keySpec);
+ }
+
+ public static KeyPair generateKeyPair() throws Exception {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, PROVIDER);
+ ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(CURVE_NAME);
+ keyPairGenerator.initialize(ecSpec, new SecureRandom());
+ return keyPairGenerator.generateKeyPair();
+ }
+
+ public static String privateKeyToPEM(PrivateKey privateKey) {
+ byte[] encoded = privateKey.getEncoded();
+ String base64 = Base64.getEncoder().encodeToString(encoded);
+ StringBuilder pem = new StringBuilder();
+ pem.append("-----BEGIN PRIVATE KEY-----\n");
+ int index = 0;
+ while (index < base64.length()) {
+ pem.append(base64.substring(index, Math.min(index + 64, base64.length())));
+ pem.append("\n");
+ index += 64;
+ }
+ pem.append("-----END PRIVATE KEY-----\n");
+ return pem.toString();
+ }
+
+ public static String publicKeyToPEM(PublicKey publicKey) {
+ byte[] encoded = publicKey.getEncoded();
+ String base64 = Base64.getEncoder().encodeToString(encoded);
+ StringBuilder pem = new StringBuilder();
+ pem.append("-----BEGIN PUBLIC KEY-----\n");
+ int index = 0;
+ while (index < base64.length()) {
+ pem.append(base64.substring(index, Math.min(index + 64, base64.length())));
+ pem.append("\n");
+ index += 64;
+ }
+ pem.append("-----END PUBLIC KEY-----\n");
+ return pem.toString();
+ }
+}
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
index af8b64d..e28d5a9 100644
--- a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfDeviceInfo.java
+++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfDeviceInfo.java
@@ -1,41 +1,36 @@
package com.sunyard.cisd;
-import java.nio.ByteBuffer;
+import com.sun.jna.Structure;
+import lombok.Data;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Data
+@Structure.FieldOrder({
+ "issuerName",
+ "deviceName",
+ "deviceSerial",
+ "deviceVersion",
+ "standardVersion",
+ "asymAlgAbility",
+ "symAlgAbility",
+ "hashAlgAbility",
+ "bufferSize"
+})
+public class SdfDeviceInfo extends Structure {
-public class SdfDeviceInfo {
public byte[] issuerName = new byte[40];
- public byte[] deviceName = new byte[40];
- public byte[] deviceSerial = new byte[40];
+ public byte[] deviceName = new byte[16];
+ public byte[] deviceSerial = new byte[16];
public int deviceVersion;
public int standardVersion;
- public int asymAlgAbility[] = new int[2];
+ 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();
+ public SdfDeviceInfo() {
+ super(ALIGN_NONE);
}
}
\ No newline at end of file
diff --git a/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfNativeLibrary.java b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfNativeLibrary.java
new file mode 100644
index 0000000..2848f9a
--- /dev/null
+++ b/device-fingerprint-tool/src/main/java/com/sunyard/cisd/SdfNativeLibrary.java
@@ -0,0 +1,13 @@
+package com.sunyard.cisd;
+
+import com.sun.jna.Library;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.PointerByReference;
+
+public interface SdfNativeLibrary extends Library {
+ int SDF_OpenDevice(PointerByReference phDeviceHandle);
+ int SDF_CloseDevice(Pointer hDeviceHandle);
+ int SDF_OpenSession(Pointer hDeviceHandle, PointerByReference phSessionHandle);
+ int SDF_CloseSession(Pointer hSessionHandle);
+ int SDF_GetDeviceInfo(Pointer hSessionHandle, SdfDeviceInfo deviceInfo);
+}
\ No newline at end of file
diff --git a/device-fingerprint-tool/src/main/resources/sm2_private_key.pem b/device-fingerprint-tool/src/main/resources/sm2_private_key.pem
new file mode 100644
index 0000000..a6f9554
--- /dev/null
+++ b/device-fingerprint-tool/src/main/resources/sm2_private_key.pem
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg7isDlcvx8WmYYw/6
+Xc25GcgDx3N19Czq6O2tz2v5Jx+gCgYIKoEcz1UBgi2hRANCAATJMA+gouZuIttR
+bqpDk/tjk4jefTgG1ncg7xuVoTVz10hFja5bbTssru4oD4Pooxz4VbTR1KIylDYo
+bLe3PyUJ
+-----END PRIVATE KEY-----
diff --git a/device-fingerprint-tool/src/main/resources/sm2_public_key.pem b/device-fingerprint-tool/src/main/resources/sm2_public_key.pem
new file mode 100644
index 0000000..021df1d
--- /dev/null
+++ b/device-fingerprint-tool/src/main/resources/sm2_public_key.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEyTAPoKLmbiLbUW6qQ5P7Y5OI3n04
+BtZ3IO8blaE1c9dIRY2uW207LK7uKA+D6KMc+FW00dSiMpQ2KGy3tz8lCQ==
+-----END PUBLIC KEY-----
diff --git a/device-fingerprint-tool/src/test/java/com/sunyard/cisd/SM2UtilTest.java b/device-fingerprint-tool/src/test/java/com/sunyard/cisd/SM2UtilTest.java
new file mode 100644
index 0000000..4b8e664
--- /dev/null
+++ b/device-fingerprint-tool/src/test/java/com/sunyard/cisd/SM2UtilTest.java
@@ -0,0 +1,75 @@
+package com.sunyard.cisd;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyPair;
+
+public class SM2UtilTest {
+
+ @Test
+ public void testGenerateAndSaveKeyPair() throws Exception {
+ KeyPair keyPair = SM2Util.generateKeyPair();
+
+ String privateKeyPEM = SM2Util.privateKeyToPEM(keyPair.getPrivate());
+ String publicKeyPEM = SM2Util.publicKeyToPEM(keyPair.getPublic());
+
+ String resourcesPath = "src/main/resources";
+ File resourcesDir = new File(resourcesPath);
+ if (!resourcesDir.exists()) {
+ resourcesDir.mkdirs();
+ }
+
+ File privateKeyFile = new File(resourcesPath + "/sm2_private_key.pem");
+ try (Writer writer = new OutputStreamWriter(new FileOutputStream(privateKeyFile), StandardCharsets.UTF_8)) {
+ writer.write(privateKeyPEM);
+ }
+ System.out.println("Private key saved to: " + privateKeyFile.getAbsolutePath());
+
+ File publicKeyFile = new File(resourcesPath + "/sm2_public_key.pem");
+ try (Writer writer = new OutputStreamWriter(new FileOutputStream(publicKeyFile), StandardCharsets.UTF_8)) {
+ writer.write(publicKeyPEM);
+ }
+ System.out.println("Public key saved to: " + publicKeyFile.getAbsolutePath());
+
+ System.out.println("\nGenerated Key Pair:");
+ System.out.println("Private Key:\n" + privateKeyPEM);
+ System.out.println("Public Key:\n" + publicKeyPEM);
+ }
+
+ @Test
+ public void testSignAndVerify() throws Exception {
+ KeyPair keyPair = SM2Util.generateKeyPair();
+
+ String testData = "Hello, SM2!";
+ byte[] data = testData.getBytes(StandardCharsets.UTF_8);
+
+ byte[] signature = SM2Util.sign(data, keyPair.getPrivate());
+ System.out.println("Signature generated, length: " + signature.length + " bytes");
+
+ boolean verified = SM2Util.verify(data, signature, keyPair.getPublic());
+ System.out.println("Signature verified: " + verified);
+
+ assert verified : "Signature verification failed";
+ }
+
+ @Test
+ public void testSignAndVerifyWithKeyFiles() throws Exception {
+ testGenerateAndSaveKeyPair();
+
+ String testData = "Test data for SM2 signature";
+ byte[] data = testData.getBytes(StandardCharsets.UTF_8);
+
+ byte[] signature = SM2Util.sign(data, "/sm2_private_key.pem");
+ System.out.println("Signature generated from file, length: " + signature.length + " bytes");
+
+ boolean verified = SM2Util.verify(data, signature, "/sm2_public_key.pem");
+ System.out.println("Signature verified from file: " + verified);
+
+ assert verified : "Signature verification with key files failed";
+ }
+}