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;
});