diff --git a/device-activation-platform/pom.xml b/device-activation-platform/pom.xml index 6d1c599..8bc4543 100644 --- a/device-activation-platform/pom.xml +++ b/device-activation-platform/pom.xml @@ -7,7 +7,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.11 + 2.7.18 @@ -18,7 +18,7 @@ Device Activation Platform - 17 + 8 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 e74d993..ca76d4a 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 @@ -6,8 +6,12 @@ import org.bouncycastle.util.encoders.Hex; import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PublicKey; import java.security.Security; import java.security.Signature; +import java.security.spec.X509EncodedKeySpec; import java.util.Base64; @Service @@ -50,12 +54,39 @@ public class DeviceActivationService { public String generateDeviceActivationPublicKey() { try { - java.security.KeyPairGenerator keyGen = java.security.KeyPairGenerator.getInstance("EC", PROVIDER); + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", PROVIDER); keyGen.initialize(256); - java.security.KeyPair keyPair = keyGen.generateKeyPair(); + KeyPair keyPair = keyGen.generateKeyPair(); return Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); } catch (Exception e) { throw new RuntimeException("生成设备激活公钥失败", e); } } + + public KeyPair generateKeyPair() { + try { + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", PROVIDER); + keyGen.initialize(256); + return keyGen.generateKeyPair(); + } catch (Exception e) { + throw new RuntimeException("生成密钥对失败", e); + } + } + + public boolean verifySm2Signature(String data, String signatureBase64, String publicKeyBase64) { + try { + byte[] keyBytes = Base64.getDecoder().decode(publicKeyBase64); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + java.security.KeyFactory keyFactory = java.security.KeyFactory.getInstance("EC", PROVIDER); + PublicKey publicKey = keyFactory.generatePublic(keySpec); + + Signature signature = Signature.getInstance(SIGNATURE_ALGO, PROVIDER); + signature.initVerify(publicKey); + signature.update(data.getBytes(StandardCharsets.UTF_8)); + byte[] signatureBytes = Base64.getDecoder().decode(signatureBase64); + return signature.verify(signatureBytes); + } catch (Exception e) { + throw new RuntimeException("SM2验签失败", e); + } + } } \ No newline at end of file diff --git a/device-activation-platform/src/test/java/com/sunyar/cisd/DeviceActivationServiceTest.java b/device-activation-platform/src/test/java/com/sunyar/cisd/DeviceActivationServiceTest.java new file mode 100644 index 0000000..48ff570 --- /dev/null +++ b/device-activation-platform/src/test/java/com/sunyar/cisd/DeviceActivationServiceTest.java @@ -0,0 +1,88 @@ +package com.sunyar.cisd; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.nio.charset.StandardCharsets; +import java.security.KeyPair; +import java.util.Base64; + +import static org.junit.jupiter.api.Assertions.*; + +class DeviceActivationServiceTest { + + private DeviceActivationService service; + + @BeforeEach + void setUp() { + service = new DeviceActivationService(); + } + + @Test + void testCalculateSm3Hash() { + String input = "test data"; + String hash = service.calculateSm3Hash(input); + assertNotNull(hash); + assertEquals(64, hash.length()); + String hash2 = service.calculateSm3Hash(input); + assertEquals(hash, hash2); + } + + @Test + void testSignAndVerifySm2Signature() { + String data = "device activation test data"; + KeyPair keyPair = service.generateKeyPair(); + String privateKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); + String publicKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); + + String signature = service.signWithSm2Pkcs1(data, privateKeyBase64); + assertNotNull(signature); + assertFalse(signature.isEmpty()); + + boolean verified = service.verifySm2Signature(data, signature, publicKeyBase64); + assertTrue(verified, "签名验签应该通过"); + } + + @Test + void testVerifySm2SignatureWithWrongData() { + String data = "original data"; + String wrongData = "modified data"; + KeyPair keyPair = service.generateKeyPair(); + String privateKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()); + String publicKeyBase64 = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()); + + String signature = service.signWithSm2Pkcs1(data, privateKeyBase64); + + boolean verified = service.verifySm2Signature(wrongData, signature, publicKeyBase64); + assertFalse(verified, "数据被篡改后验签应该失败"); + } + + @Test + void testVerifySm2SignatureWithWrongKey() { + String data = "test data"; + KeyPair keyPair1 = service.generateKeyPair(); + KeyPair keyPair2 = service.generateKeyPair(); + String privateKeyBase64 = Base64.getEncoder().encodeToString(keyPair1.getPrivate().getEncoded()); + String wrongPublicKeyBase64 = Base64.getEncoder().encodeToString(keyPair2.getPublic().getEncoded()); + + String signature = service.signWithSm2Pkcs1(data, privateKeyBase64); + + boolean verified = service.verifySm2Signature(data, signature, wrongPublicKeyBase64); + assertFalse(verified, "使用错误的公钥验签应该失败"); + } + + @Test + void testGenerateDeviceActivationPublicKey() { + String publicKey = service.generateDeviceActivationPublicKey(); + assertNotNull(publicKey); + assertFalse(publicKey.isEmpty()); + } + + @Test + void testGenerateKeyPair() { + KeyPair keyPair = service.generateKeyPair(); + assertNotNull(keyPair); + assertNotNull(keyPair.getPublic()); + assertNotNull(keyPair.getPrivate()); + } +} \ No newline at end of file