diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java index 24c3c23..af7c42b 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/BcSdfApiAdaptor.java @@ -137,7 +137,7 @@ public class BcSdfApiAdaptor implements SdfApiAdapter { @Override public EccSignature externalSignECC(String sessionHandle, EccPriKey privateKey, byte[] pucData) { - ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(getD()); + ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(privateKey.getD()); try { SM2Signer signer = new SM2Signer(new NullDigest()); signer.init(true, pri); @@ -173,7 +173,7 @@ public class BcSdfApiAdaptor implements SdfApiAdapter { @Override public byte[] externalDecryptECC(String sessionHandle, EccPriKey pucPrivateKeyEcc, EccCipher pucEncData) { - ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(getD()); + ECPrivateKeyParameters pri = BCECUtils.createECPrivateKeyParameters(pucPrivateKeyEcc.getD()); try { return BCSM2Utils.decrypt(pri, LangUtils.merge(new byte[]{0x04}, pucEncData.getC1C3C2Bytes())); } catch (InvalidCipherTextException e) { diff --git a/chsm-web-server/pom.xml b/chsm-web-server/pom.xml index bbd7030..749e3c6 100644 --- a/chsm-web-server/pom.xml +++ b/chsm-web-server/pom.xml @@ -56,5 +56,20 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + \ No newline at end of file diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/config/WebConfig.java b/chsm-web-server/src/main/java/com/sunyard/chsm/config/WebConfig.java index 61d2ecb..482a5c1 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/config/WebConfig.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/config/WebConfig.java @@ -1,11 +1,26 @@ package com.sunyard.chsm.config; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import com.sunyard.chsm.auth.AuthHandler; +import com.sunyard.chsm.utils.DateFormat; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; + /** * @author liulu * @since 2024/12/6 @@ -25,5 +40,22 @@ public class WebConfig { } + @Bean + public Jackson2ObjectMapperBuilderCustomizer objectMapperBuilderCustomizer() { + return builder -> { + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateFormat.TIME)); + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateFormat.DATE)); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateFormat.DATE_TIME)); + + javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateFormat.TIME)); + javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateFormat.DATE)); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateFormat.DATE_TIME)); + builder.modules(javaTimeModule); + builder.serializerByType(Long.class, ToStringSerializer.instance); + builder.serializationInclusion(JsonInclude.Include.NON_NULL); + builder.failOnUnknownProperties(false); + }; + } } diff --git a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiTest.java b/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiTest.java new file mode 100644 index 0000000..09e1740 --- /dev/null +++ b/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/SdfApiTest.java @@ -0,0 +1,151 @@ +package com.sunyard.chsm.sdf; + +import com.googlecode.jsonrpc4j.JsonRpcHttpClient; +import com.googlecode.jsonrpc4j.ProxyUtil; +import com.sunyard.chsm.sdf.adapter.RpcSdfAdapter; +import com.sunyard.chsm.sdf.adapter.SdfApiAdapter; +import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory; +import com.sunyard.chsm.sdf.context.AlgId; +import com.sunyard.chsm.sdf.model.DeviceInfo; +import com.sunyard.chsm.sdf.model.EccCipher; +import com.sunyard.chsm.sdf.model.EccKey; +import com.sunyard.chsm.sdf.model.EccPriKey; +import com.sunyard.chsm.sdf.model.EccPubKey; +import com.sunyard.chsm.utils.CodecUtils; +import com.sunyard.chsm.utils.JsonUtils; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.net.URL; +import java.util.Collections; +import java.util.Optional; + +/** + * @author liulu + * @since 2024/12/12 + */ +@Slf4j +class SdfApiTest { + + private final byte[] symKey = "nhkdhaksd4678787".getBytes(); + private final byte[] iv = "hjdashde83252i23".getBytes(); + private final String plain = "hello sdf api ,hello sdf api !&!"; + private final String ip1 = "172.16.18.41"; + private final int port = 8889; + + private RpcSdfAdapter rpcSdfAdapter; + private String hd; + private String hs; + private EccPubKey pubKey; + private EccPriKey priKey; + private SdfApiAdapter bcAdapter = SdfApiAdapterFactory.getBcAdapter(); + + @BeforeEach + public void before() throws Exception { + JsonRpcHttpClient client = new JsonRpcHttpClient(JsonUtils.objectMapper(), + new URL("http://172.16.18.46:9989/sdf/adapter"), Collections.emptyMap()); + rpcSdfAdapter = ProxyUtil.createClientProxy( + getClass().getClassLoader(), RpcSdfAdapter.class, client); + this.hd = rpcSdfAdapter.openDevice(ip1, port, 3000, 3000, 0); + this.hs = rpcSdfAdapter.openSession(hd); + EccKey eccKey = rpcSdfAdapter.generateKeyPairECC(hs, AlgId.SGD_SM2_3); + pubKey = EccPubKey.fromBytes(eccKey.getPubKey()); + priKey = EccPriKey.fromBytes(eccKey.getPriKey()); + } + + @AfterEach + public void after() { + Optional.ofNullable(hs).ifPresent(rpcSdfAdapter::closeSession); + Optional.ofNullable(hd).ifPresent(rpcSdfAdapter::closeDevice); + } + + @Test + public void getDeviceInfo() { + DeviceInfo deviceInfo = rpcSdfAdapter.getDeviceInfo(hs); + Assertions.assertNotNull(deviceInfo); + log.info("DeviceInfo: {}", deviceInfo); + } + + @Test + public void testSymEncAndDec() { + String hk = rpcSdfAdapter.importKey(hs, symKey); + byte[] ecbCipher = rpcSdfAdapter.symEncrypt(hs, hk, AlgId.SGD_SM4_ECB, null, plain.getBytes()); + byte[] ecbPlain = rpcSdfAdapter.symDecrypt(hs, hk, AlgId.SGD_SM4_ECB, null, ecbCipher); + log.info("ecb_cipher: {}", CodecUtils.encodeHex(ecbCipher)); + Assertions.assertEquals(plain, new String(ecbPlain)); + + byte[] cbcCipher = rpcSdfAdapter.symEncrypt(hs, hk, AlgId.SGD_SM4_CBC, iv, plain.getBytes()); + log.info("cbc_cipher: {}", CodecUtils.encodeHex(cbcCipher)); + byte[] cbcPlain = rpcSdfAdapter.symDecrypt(hs, hk, AlgId.SGD_SM4_CBC, iv, cbcCipher); + Assertions.assertEquals(plain, new String(cbcPlain)); + rpcSdfAdapter.destroyKey(hs, hk); + + Assertions.assertArrayEquals(ecbPlain, cbcPlain); + Assertions.assertNotEquals(CodecUtils.encodeHex(ecbCipher), CodecUtils.encodeHex(cbcCipher)); + + + String bchk = bcAdapter.importKey("", symKey); + byte[] bcEcbCipher = bcAdapter.symEncrypt("", bchk, AlgId.SGD_SM4_ECB, null, plain.getBytes()); + log.info("bc_ecb_cipher: {}", CodecUtils.encodeHex(bcEcbCipher)); + Assertions.assertArrayEquals(ecbCipher, bcEcbCipher); + + byte[] bcCbcCipher = bcAdapter.symEncrypt("", bchk, AlgId.SGD_SM4_CBC, iv, plain.getBytes()); + log.info("bc_cbc_cipher: {}", CodecUtils.encodeHex(bcCbcCipher)); + bcAdapter.destroyKey(hs, bchk); + Assertions.assertArrayEquals(cbcCipher, bcCbcCipher); + } + + @Test + public void testSM2EncAndDec() { + EccCipher sdfCipher = rpcSdfAdapter.externalEncryptECC(hs, pubKey, plain.getBytes()); + log.info("sdf sm2 cipher: {}", sdfCipher.getC1C3C2Hex()); + byte[] bcPlain = bcAdapter.externalDecryptECC("", priKey, sdfCipher); + log.info("bc sm2 plain: {}", new String(bcPlain)); + Assertions.assertEquals(plain, new String(bcPlain)); + + EccCipher bcCipher = bcAdapter.externalEncryptECC("", pubKey, plain.getBytes()); + log.info("bc sm2 cipher: {}", bcCipher.getC1C3C2Hex()); + byte[] sm2Plain = rpcSdfAdapter.externalDecryptECC(hs, priKey, bcCipher); + log.info("sdf sm2 plain: {}", new String(sm2Plain)); + + Assertions.assertEquals(plain, new String(sm2Plain)); + } + + @Test + public void testHash() { + String newSession = rpcSdfAdapter.openSession(hd); + rpcSdfAdapter.hashInit(newSession, AlgId.SGD_SM3, null, new byte[0]); + rpcSdfAdapter.hashUpdate(newSession, plain.getBytes()); + byte[] hash = rpcSdfAdapter.hashFinish(newSession); + log.info("sdf hash: {}", CodecUtils.encodeHex(hash)); + rpcSdfAdapter.closeSession(newSession); + + String bcNewSession = bcAdapter.openSession(""); + bcAdapter.hashInit(bcNewSession, AlgId.SGD_SM3, null, new byte[0]); + bcAdapter.hashUpdate(bcNewSession, plain.getBytes()); + byte[] bcHash = bcAdapter.hashFinish(bcNewSession); + log.info("bc hash: {}", CodecUtils.encodeHex(bcHash)); + bcAdapter.closeSession(bcNewSession); + + Assertions.assertArrayEquals(hash, bcHash); + } + + @Test + public void testSm4Mac() { + String hk = rpcSdfAdapter.importKey(hs, symKey); + byte[] sdfMac = rpcSdfAdapter.calculateMAC(hs, hk, AlgId.SGD_SM4_MAC, iv, plain.getBytes()); + log.info("sdf mac: {}", CodecUtils.encodeHex(sdfMac)); + rpcSdfAdapter.destroyKey(hs, hk); + + String bchk = bcAdapter.importKey("", symKey); + byte[] bcMac = bcAdapter.calculateMAC("", bchk, AlgId.SGD_SM4_MAC, iv, plain.getBytes()); + log.info("bc mac: {}", CodecUtils.encodeHex(bcMac)); + bcAdapter.destroyKey("", bchk); + Assertions.assertArrayEquals(sdfMac, bcMac); + } + + +} diff --git a/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java b/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java new file mode 100644 index 0000000..9e413b9 --- /dev/null +++ b/chsm-web-server/src/test/java/com/sunyard/chsm/sdf/adapter/RpcSdfAdapter.java @@ -0,0 +1,11 @@ +package com.sunyard.chsm.sdf.adapter; + +/** + * @author liulu + * @since 2024/12/12 + */ +public interface RpcSdfAdapter extends SdfApiAdapter { + + String openDevice(String ip, int port, int connTimeout, int dealTimeout, int ipMode); + +} diff --git a/pom.xml b/pom.xml index 817c94b..fceb96f 100644 --- a/pom.xml +++ b/pom.xml @@ -42,7 +42,12 @@ junit test - + + com.github.briandilley.jsonrpc4j + jsonrpc4j + 1.6 + test +