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"; + } +}