diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/SdfApiService.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/SdfApiService.java index 964be67..f859b45 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/SdfApiService.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/SdfApiService.java @@ -80,9 +80,9 @@ public interface SdfApiService { * @param userId 签名者id * @return pucSignature 返回签名值数据 */ - EccSignature externalSignWithId(byte[] privateKey, byte[] pucData, byte[] userId); + EccSignature externalSignWithIdECC(byte[] privateKey, byte[] pucData, byte[] userId); - EccSignature externalSign(byte[] privateKey, byte[] pucData); + EccSignature externalSignECC(byte[] privateKey, byte[] pucData); /** * 外部密钥ECC验证 @@ -93,9 +93,9 @@ public interface SdfApiService { * @param signData 外部签名数据 * @return 0 成功; 非0 失败,返回错误代码 */ - boolean externalVerifyWithId(byte[] publicKey, byte[] pubData, byte[] signData, byte[] userId); + boolean externalVerifyWithIdECC(byte[] publicKey, byte[] pubData, byte[] signData, byte[] userId); - boolean externalVerify(byte[] publicKey, byte[] pubData, byte[] signData); + boolean externalVerifyECC(byte[] publicKey, byte[] pubData, byte[] signData); /** @@ -105,7 +105,7 @@ public interface SdfApiService { * @param pucData 缓冲区指针,用于存放外部输入的数据 * @return pucEncData 返回数据密文 */ - EccCipher externalEncrypt(byte[] publicKey, byte[] pucData); + EccCipher externalEncryptECC(byte[] publicKey, byte[] pucData); /** * 外部密钥ECC私钥解密 @@ -114,7 +114,7 @@ public interface SdfApiService { * @param encData 缓冲区指针,用于存放输入的数据密文 * @return pucData 返回数据明文 */ - byte[] externalDecrypt(byte[] privateKey, byte[] encData); + byte[] externalDecryptECC(byte[] privateKey, byte[] encData); /** * 计算MAC diff --git a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/JnaSdfAdaptor.java b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/JnaSdfAdaptor.java index 0bfda4f..ac8599e 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/JnaSdfAdaptor.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/sdf/adapter/JnaSdfAdaptor.java @@ -269,7 +269,7 @@ public abstract class JnaSdfAdaptor implements SdfApiAdapter { public int hashInit(String sessionHandle, AlgId alg, EccPubKey pucPublicKey, byte[] pucID) { Pointer hSessionHandle = getSessionHandle(sessionHandle); byte[] pubPub = pucPublicKey == null ? null : pucPublicKey.toSdfData(); - return sdfLibrary.SDF_HashInit(hSessionHandle, getAlgId(AlgId.SGD_SM3), pubPub, pucID, pucID.length); + return sdfLibrary.SDF_HashInit(hSessionHandle, getAlgId(AlgId.SGD_SM3), pubPub, pucID, pucID == null ? 0 : pucID.length); } @Override diff --git a/chsm-web-manage/pom.xml b/chsm-web-manage/pom.xml index 5397ab4..76c8cc3 100644 --- a/chsm-web-manage/pom.xml +++ b/chsm-web-manage/pom.xml @@ -105,6 +105,11 @@ jjwt + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java b/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java index 13bd6d0..91df4ff 100644 --- a/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java +++ b/chsm-web-manage/src/main/java/com/sunyard/chsm/sdf/SingleSdfApiService.java @@ -87,12 +87,12 @@ public class SingleSdfApiService implements SdfApiService, InitializingBean { } @Override - public EccSignature externalSign(byte[] privateKey, byte[] pucData) { - return externalSignWithId(privateKey, pucData, new byte[0]); + public EccSignature externalSignECC(byte[] privateKey, byte[] pucData) { + return externalSignWithIdECC(privateKey, pucData, new byte[0]); } @Override - public EccSignature externalSignWithId(byte[] privateKey, byte[] pucData, byte[] userId) { + public EccSignature externalSignWithIdECC(byte[] privateKey, byte[] pucData, byte[] userId) { EccPriKey sdfEccPrivateKey = EccPriKey.fromBytes(privateKey); SM2PreprocessSigner signer = new SM2PreprocessSigner(); CipherParameters keyParameters = BCECUtils.createECPrivateKeyParameters(sdfEccPrivateKey.getD()); @@ -105,7 +105,7 @@ public class SingleSdfApiService implements SdfApiService, InitializingBean { } @Override - public boolean externalVerifyWithId(byte[] publicKey, byte[] pubData, byte[] signData, byte[] userId) { + public boolean externalVerifyWithIdECC(byte[] publicKey, byte[] pubData, byte[] signData, byte[] userId) { EccPubKey eccPublicKey = EccPubKey.fromBytes(publicKey); CipherParameters parameters = BCECUtils.createECPublicKeyParameters(eccPublicKey.getX(), eccPublicKey.getY()); if (userId != null && userId.length > 0) { @@ -120,18 +120,18 @@ public class SingleSdfApiService implements SdfApiService, InitializingBean { } @Override - public boolean externalVerify(byte[] publicKey, byte[] pubData, byte[] signData) { - return externalVerifyWithId(publicKey, pubData, signData, new byte[0]); + public boolean externalVerifyECC(byte[] publicKey, byte[] pubData, byte[] signData) { + return externalVerifyWithIdECC(publicKey, pubData, signData, new byte[0]); } @Override - public EccCipher externalEncrypt(byte[] publicKey, byte[] pucData) { + public EccCipher externalEncryptECC(byte[] publicKey, byte[] pucData) { EccPubKey eccPublicKey = EccPubKey.fromBytes(publicKey); return sdfApiAdapter.externalEncryptECC(sessionHandle, eccPublicKey, pucData); } @Override - public byte[] externalDecrypt(byte[] privateKey, byte[] encData) { + public byte[] externalDecryptECC(byte[] privateKey, byte[] encData) { EccPriKey sdfEccPrivateKey = EccPriKey.fromBytes(privateKey); EccCipher eccCipher = EccCipher.fromBytes(encData); return sdfApiAdapter.externalDecryptECC(sessionHandle, sdfEccPrivateKey, eccCipher); @@ -141,7 +141,7 @@ public class SingleSdfApiService implements SdfApiService, InitializingBean { public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) { checkStatus(); String hk = sdfApiAdapter.importKey(sessionHandle, symKey); - byte[] mac = sdfApiAdapter.calculateMAC(sessionHandle, hk, AlgId.SGD_SM4_MAC, pucIv, pucData); + byte[] mac = sdfApiAdapter.calculateMAC(sessionHandle, hk, AlgId.SGD_SM4_MAC, pucIv, PaddingUtil.PKCS7Padding(pucData)); sdfApiAdapter.destroyKey(sessionHandle, hk); return mac; } diff --git a/chsm-web-manage/src/test/java/sdf/SdfApiServiceTest.java b/chsm-web-manage/src/test/java/sdf/SdfApiServiceTest.java new file mode 100644 index 0000000..205edac --- /dev/null +++ b/chsm-web-manage/src/test/java/sdf/SdfApiServiceTest.java @@ -0,0 +1,142 @@ +package sdf; + +import com.sunyard.chsm.sdf.SdfApiService; +import com.sunyard.chsm.sdf.SingleSdfApiService; +import com.sunyard.chsm.sdf.adapter.SdfApiAdapterFactory; +import com.sunyard.chsm.sdf.context.AlgId; +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.sdf.model.EccSignature; +import com.sunyard.chsm.utils.CodecUtils; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +/** + * @author liulu + * @since 2024/12/13 + */ +@Slf4j +public class SdfApiServiceTest { + + private final static byte[] symKey = "nhkdhaksd4678787".getBytes(); + private final static byte[] iv = "hjdashde83252i23".getBytes(); + private final static String plain = "hello sdf api ,hello sdf api !&!----->"; + private final static String ip1 = "172.16.18.41"; + private final static int port = 8889; + private static final SdfApiService bcService = new SingleSdfApiService(SdfApiAdapterFactory.getBcAdapter()); + private static final SdfApiService sdfService = new SingleSdfApiService(SdfApiAdapterFactory.getProxyRcpAdapter(ip1, port)); + + private static EccPubKey pubKey; + private static EccPriKey priKey; + + + @BeforeAll + public static void before() throws Exception { + EccKey eccKey = sdfService.genKeyPairEcc(); + pubKey = EccPubKey.fromBytes(eccKey.getPubKey()); + priKey = EccPriKey.fromBytes(eccKey.getPriKey()); + log.info("public key: {}", pubKey.getPubKeyHex()); + log.info("private key: {}", CodecUtils.encodeHex(priKey.getD())); + } + + @Test + public void testRandom() { + byte[] sdfRandom = sdfService.generateRandom(64); + log.info("sdf Random: {}", CodecUtils.encodeHex(sdfRandom)); + Assertions.assertEquals(64, sdfRandom.length); + + byte[] bcRandom = bcService.generateRandom(64); + log.info("bc Random: {}", CodecUtils.encodeHex(bcRandom)); + Assertions.assertEquals(64, bcRandom.length); + + Assertions.assertFalse(Arrays.equals(sdfRandom, bcRandom)); + } + + @Test + public void testSM2EncAndDec() { + EccCipher sdfCipher = sdfService.externalEncryptECC(pubKey.getPubKeyBytes(), plain.getBytes()); + log.info("sdf sm2 cipher: {}", sdfCipher.getC1C3C2Hex()); + byte[] bcPlain = bcService.externalDecryptECC(priKey.getD(), sdfCipher.getC1C3C2Bytes()); + log.info("bc sm2 plain: {}", new String(bcPlain)); + Assertions.assertEquals(plain, new String(bcPlain)); + + EccCipher bcCipher = bcService.externalEncryptECC(pubKey.getPubKeyBytes(), plain.getBytes()); + log.info("bc sm2 cipher: {}", bcCipher.getC1C3C2Hex()); + byte[] sm2Plain = sdfService.externalDecryptECC(priKey.getD(), bcCipher.getC1C3C2Bytes()); + log.info("sdf sm2 plain: {}", new String(sm2Plain)); + Assertions.assertEquals(plain, new String(sm2Plain)); + } + + @Test + public void testSM2SignAndVerify() { + EccSignature bcSign = bcService.externalSignECC(priKey.getD(), plain.getBytes()); + log.info("bc sm2 signature: {}", bcSign.getRawSignHex()); + boolean sdfVerified = sdfService.externalVerifyECC(pubKey.getPubKeyBytes(), plain.getBytes(), bcSign.getDerSignBytes()); + log.info("sdf sm2 verified: {}", sdfVerified); + Assertions.assertTrue(sdfVerified); + + EccSignature sdfSign = sdfService.externalSignECC(priKey.getD(), plain.getBytes()); + log.info("sdf sm2 signature: {}", sdfSign.getRawSignHex()); + boolean bcVerified = bcService.externalVerifyECC(pubKey.getPubKeyBytes(), plain.getBytes(), sdfSign.getRawSignBytes()); + log.info("bc sm2 verified: {}", bcVerified); + Assertions.assertTrue(bcVerified); + } + + + @Test + public void testSymEncAndDec() { + byte[] ecbCipher = sdfService.symEncrypt(AlgId.SGD_SM4_ECB, symKey, null, plain.getBytes()); + byte[] ecbPlain = sdfService.symDecrypt(AlgId.SGD_SM4_ECB, symKey, null, ecbCipher); + log.info("ecb_cipher: {}", CodecUtils.encodeHex(ecbCipher)); + Assertions.assertEquals(plain, new String(ecbPlain)); + + byte[] cbcCipher = sdfService.symEncrypt(AlgId.SGD_SM4_CBC, symKey, iv, plain.getBytes()); + log.info("cbc_cipher: {}", CodecUtils.encodeHex(cbcCipher)); + byte[] cbcPlain = sdfService.symDecrypt(AlgId.SGD_SM4_CBC, symKey, iv, cbcCipher); + Assertions.assertEquals(plain, new String(cbcPlain)); + + Assertions.assertArrayEquals(ecbPlain, cbcPlain); + Assertions.assertNotEquals(CodecUtils.encodeHex(ecbCipher), CodecUtils.encodeHex(cbcCipher)); + + + byte[] bcEcbCipher = bcService.symEncrypt(AlgId.SGD_SM4_ECB, symKey, null, plain.getBytes()); + log.info("bc_ecb_cipher: {}", CodecUtils.encodeHex(bcEcbCipher)); + Assertions.assertArrayEquals(ecbCipher, bcEcbCipher); + byte[] bcCbcCipher = bcService.symEncrypt(AlgId.SGD_SM4_CBC, symKey, iv, plain.getBytes()); + log.info("bc_cbc_cipher: {}", CodecUtils.encodeHex(bcCbcCipher)); + Assertions.assertArrayEquals(cbcCipher, bcCbcCipher); + } + + @Test + public void testSm4Mac() { + byte[] sdfMac = sdfService.calculateMAC(symKey, iv, plain.getBytes()); + log.info("sdf mac: {}", CodecUtils.encodeHex(sdfMac)); + Assertions.assertEquals(16, sdfMac.length); + + byte[] bcMac = bcService.calculateMAC(symKey, iv, plain.getBytes()); + log.info("bc mac: {}", CodecUtils.encodeHex(bcMac)); + Assertions.assertEquals(16, bcMac.length); + + Assertions.assertArrayEquals(sdfMac, bcMac); + } + + @Test + public void testSm3() { + byte[] sdfHash = sdfService.hash(plain.getBytes()); + log.info("sdf hash: {}", CodecUtils.encodeHex(sdfHash)); + Assertions.assertEquals(32, sdfHash.length); + + byte[] bcHash = bcService.hash(plain.getBytes()); + log.info("bc hash: {}", CodecUtils.encodeHex(bcHash)); + Assertions.assertEquals(32, bcHash.length); + + Assertions.assertArrayEquals(sdfHash, bcHash); + } + +} diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/pool/LoadBalancedSdfApiService.java b/chsm-web-server/src/main/java/com/sunyard/chsm/pool/LoadBalancedSdfApiService.java index 319b2f5..b5aab50 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/pool/LoadBalancedSdfApiService.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/pool/LoadBalancedSdfApiService.java @@ -72,12 +72,12 @@ public class LoadBalancedSdfApiService implements SdfApiService { } @Override - public EccSignature externalSign(byte[] privateKey, byte[] pucData) { - return externalSignWithId(privateKey, pucData, new byte[0]); + public EccSignature externalSignECC(byte[] privateKey, byte[] pucData) { + return externalSignWithIdECC(privateKey, pucData, new byte[0]); } @Override - public EccSignature externalSignWithId(byte[] privateKey, byte[] pucData, byte[] userId) { + public EccSignature externalSignWithIdECC(byte[] privateKey, byte[] pucData, byte[] userId) { EccPriKey sdfEccPrivateKey = EccPriKey.fromBytes(privateKey); SM2PreprocessSigner signer = new SM2PreprocessSigner(); CipherParameters keyParameters = BCECUtils.createECPrivateKeyParameters(sdfEccPrivateKey.getD()); @@ -91,7 +91,7 @@ public class LoadBalancedSdfApiService implements SdfApiService { } @Override - public boolean externalVerifyWithId(byte[] publicKey, byte[] pubData, byte[] signData, byte[] userId) { + public boolean externalVerifyWithIdECC(byte[] publicKey, byte[] pubData, byte[] signData, byte[] userId) { EccPubKey eccPublicKey = EccPubKey.fromBytes(publicKey); CipherParameters parameters = BCECUtils.createECPublicKeyParameters(eccPublicKey.getX(), eccPublicKey.getY()); if (userId != null && userId.length > 0) { @@ -107,18 +107,18 @@ public class LoadBalancedSdfApiService implements SdfApiService { } @Override - public boolean externalVerify(byte[] publicKey, byte[] pubData, byte[] signData) { - return externalVerifyWithId(publicKey, pubData, signData, new byte[0]); + public boolean externalVerifyECC(byte[] publicKey, byte[] pubData, byte[] signData) { + return externalVerifyWithIdECC(publicKey, pubData, signData, new byte[0]); } @Override - public EccCipher externalEncrypt(byte[] publicKey, byte[] pucData) { + public EccCipher externalEncryptECC(byte[] publicKey, byte[] pucData) { EccPubKey eccPublicKey = EccPubKey.fromBytes(publicKey); return apply(s -> s.getSdfApiAdapter().externalEncryptECC(s.getSessionHandle(), eccPublicKey, pucData)); } @Override - public byte[] externalDecrypt(byte[] privateKey, byte[] encData) { + public byte[] externalDecryptECC(byte[] privateKey, byte[] encData) { EccPriKey sdfEccPrivateKey = EccPriKey.fromBytes(privateKey); EccCipher eccCipher = EccCipher.fromBytes(encData); return apply(s -> s.getSdfApiAdapter().externalDecryptECC(s.getSessionHandle(), sdfEccPrivateKey, eccCipher)); @@ -128,7 +128,7 @@ public class LoadBalancedSdfApiService implements SdfApiService { public byte[] calculateMAC(byte[] symKey, byte[] pucIv, byte[] pucData) { return apply(s -> { String keyHandle = s.getSdfApiAdapter().importKey(s.getSessionHandle(), symKey); - byte[] mac = s.getSdfApiAdapter().calculateMAC(s.getSessionHandle(), keyHandle, AlgId.SGD_SM4_MAC, pucIv, pucData); + byte[] mac = s.getSdfApiAdapter().calculateMAC(s.getSessionHandle(), keyHandle, AlgId.SGD_SM4_MAC, pucIv, PaddingUtil.PKCS7Padding(pucData)); s.getSdfApiAdapter().destroyKey(s.getSessionHandle(), keyHandle); return mac; });