diff --git a/DProto/6A.xml b/DProto/6A.xml
index 30f4544..37b25e0 100644
--- a/DProto/6A.xml
+++ b/DProto/6A.xml
@@ -14,6 +14,9 @@
+
@@ -50,6 +53,14 @@
LMK 下加密密钥的方案。
+
+ 公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
+
+
+
+ 公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
+
+
可选项。如果显示消息尾域,则该域必须显示。值为
“X’19”。
@@ -140,29 +151,50 @@
-
+ function lmkLen() {
+ if( Arrays.equals("L".getBytes(),
+ $final.getSection('data').getSection('lmkHead').getValue()
+ ) ){
+ return 64
+ }else{
+ return 32
+ }
+ }
+
+ > 8 & 0xFF)
+ data[1] = (byte)(len & 0xFF)
+
+ return data;
+ }
+ ]]>
+
diff --git a/DProto/6B.xml b/DProto/6B.xml
index a67bb3c..9cd0fc2 100644
--- a/DProto/6B.xml
+++ b/DProto/6B.xml
@@ -120,6 +120,14 @@
密钥校验值
+
+ 公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
+
+
+
+ 公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
+
+
可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。
19
@@ -133,32 +141,37 @@
-
+ function lmkLen() {
+ if( Arrays.equals("L".getBytes(),
+ $final.getSection('data').getSection('lmkHead').getValue()
+ ) ){
+ return 64
+ }else{
+ return 32
+ }
+ }
+ function orgCodeLen() {
+ return Util.a2i( $final.getSection('data').getSection('orgCodeLen') )
+ }
+
diff --git a/doc/java接口说明文档.docx b/doc/java接口说明文档.docx
index e176303..c2f88f6 100644
Binary files a/doc/java接口说明文档.docx and b/doc/java接口说明文档.docx differ
diff --git a/pom.xml b/pom.xml
index 1036450..c5a5e6e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,7 +77,7 @@
com.sunyard
dproto
- 1.0-20211220
+ 1.0-20220107
diff --git a/src/main/java/com/sunyard/inf/SydCryptionApi.java b/src/main/java/com/sunyard/inf/SydCryptionApi.java
index 2ee413b..b41d45b 100644
--- a/src/main/java/com/sunyard/inf/SydCryptionApi.java
+++ b/src/main/java/com/sunyard/inf/SydCryptionApi.java
@@ -95,6 +95,16 @@ interface SydASYMApi {
);
+ /**
+ * 用指定的 SM2 公钥对指定的密文数据进行加密。
+ * 输出的sm2密文结构为C1C2C3格式
+ * @param publicKey 公钥钥串,DER 编码,HEX 格式。
+ * @param pOrgData 加密的数据。
+ * @return 加密的数据 base64 编码。
+ */
+ String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData);
+
+
/**
* 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
*
@@ -112,6 +122,15 @@ interface SydASYMApi {
*/
byte[] SM2Decrypt(byte[] sk, String enData);
+ /**
+ * 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
+ * 输入的sm2密文结构为C1C2C3格式
+ * @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
+ * @param enData 加密的数据,base64 编码。
+ * @return 明文数据。
+ */
+ byte[] SM2DecryptOrder(String userId, String enData);
+
/**
* 用指定的 RSA 私钥对指定的密文数据进行加密。
*
diff --git a/src/main/java/com/sunyard/inf/SydGenApi.java b/src/main/java/com/sunyard/inf/SydGenApi.java
index e13a18e..421227b 100644
--- a/src/main/java/com/sunyard/inf/SydGenApi.java
+++ b/src/main/java/com/sunyard/inf/SydGenApi.java
@@ -228,6 +228,18 @@ public interface SydGenApi {
*/
RetWrap generateDEbyGS(String certSerial, byte nAlg);
+ /**
+ * 产生对称密钥,通过公钥加密生成网联格式的数字信封。
+ *
+ * @param certSerial 对*方 X509 证书的序列号。
+ * @param orgCode 机构码
+ * @return RetWrap 包含 CipherKey, SessionKey, KCV
+ * CipherKey 公钥加密的会话密钥 ,BASE64 编码
+ * SessionKey 本地LMK 加密的会话密钥,HEX 格式, 本地 LMK 加密的会话密钥长度,HEX 格式(不包括第 1 个字符),一般为 33 个 Bytes。默认输入值为缓冲区的大小。
+ * KCV 会话密钥的检验值,HEX 格式,长度为 32H。
+ */
+ RetWrap generateDEbyGS(String certSerial, String orgCode);
+
/**
* 产生对称密钥,通过公钥加密生成网联格式的数字信封。
@@ -252,6 +264,7 @@ public interface SydGenApi {
* @return RetWrap 包含 SessionKey KCV
* SessionKey 输出。 本地LMK 加密的会话密钥,格式为:密钥类型|密钥密文,比如:02|密钥密文
* KCV 会话密钥的检验值,HEX 格式,长度为 36H。
+ * orgCode 如果有机构码的话会返回机构码
*/
RetWrap decryptDE(
String pCertSerial,
diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java
index 70ad057..47f065c 100644
--- a/src/main/java/racal/sunyard/main/SydApi4j.java
+++ b/src/main/java/racal/sunyard/main/SydApi4j.java
@@ -2129,15 +2129,20 @@ public class SydApi4j implements SydApi {
@Override
public RetWrap generateDEbyGS(String certSerial, byte nAlg) {
- return generateDE(1, certSerial, nAlg);
+ return generateDE(1, certSerial, nAlg, null);
+ }
+
+ @Override
+ public RetWrap generateDEbyGS(String certSerial, String orgCode) {
+ return generateDE(1, certSerial, (byte) 0x32, orgCode);
}
@Override
public RetWrap generateDE(String certSerial, byte nAlg) {
- return generateDE(0, certSerial, nAlg);
+ return generateDE(0, certSerial, nAlg, null);
}
- public RetWrap generateDE(int pFlag, String certSerial, byte nAlg) {
+ private RetWrap generateDE(int pFlag, String certSerial, byte nAlg, String orgCode) {
// 获取协议
//ProtocolRender render = pset.getProtocolReqRender("6A");
Proto6A proto = new Proto6A();
@@ -2149,6 +2154,14 @@ public class SydApi4j implements SydApi {
data.put("alg$option", nAlg - 0x30);
if (pFlag == 1) {
data.put("pFlag", 'P');
+
+ if (nAlg == 0x32) {
+ if (orgCode.length() != 14) {
+ throw new SydApiException("机构码长度错(只能==14)", -6);
+ }
+
+ data.put("orgCode", orgCode);
+ }
}
data.put("certificateModel$option", 0);
data.put("certificateSn", certSerial.getBytes());
@@ -2225,6 +2238,11 @@ public class SydApi4j implements SydApi {
}
RetWrap rw = new RetWrap();
+ int orgCodeLen = Util.a2i(((PacketSection) ret.get("orgCodeLen")).getBytes(), 10);
+ if (orgCodeLen != 0) {
+ rw.put("orgCode", ((PacketSection) ret.get("orgCode")).getString());
+ }
+
rw.put(SydApi.RET_SESSION_KEY, ((PacketSection) ret.get("lmkHead")).getString() +
((PacketSection) ret.get("lmk")).getString()
);
@@ -3974,6 +3992,43 @@ public class SydApi4j implements SydApi {
}
+ @Override
+ public String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData) {
+ Proto77 proto = new Proto77();
+
+ // 填充数据
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ packet.put("data", data);
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("AlgorithmKey$option", 1);
+ data.put("publicKey", publicKey);
+ data.put("infoData", pOrgData);
+ // 渲染发送
+ ByteBuffer bb = proto.rend(packet);
+ synchronized (this) {
+ // 响应解析
+ bb = syncRead(syncSend(bb));
+ }
+ //ProtocolParser parser = pset.getProtocolResParse();
+ Packet p = proto.parse(bb);
+ Map ret = p.toMap();
+ if (
+ !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
+ ) {
+ throw new SydApiException("包序号不匹配", -4);
+ }
+ ret = (Map) ret.get("data");
+ PacketSection error = (PacketSection) ret.get("error");
+ if (!"00".equals(error.getString())) {
+ throw new SydApiException(error.getInfo(), error.autoInt());
+ }
+
+ System.out.println("内部输出: " + Util.bytes2HexString(((PacketSection) ret.get("cipherData")).getBytes()));
+
+ return SYMUtil.derEnData2Base64EnC1C2C3(((PacketSection) ret.get("cipherData")).getBytes());
+ }
@Override
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
@@ -4092,6 +4147,54 @@ public class SydApi4j implements SydApi {
return ((PacketSection) ret.get("data")).getBytes();
}
+ /**
+ * 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
+ * 输入的sm2密文结构为C1C2C3格式
+ * @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
+ * @param enData 加密的数据,base64 编码。
+ * @return 明文数据。
+ */
+ @Override
+ public byte[] SM2DecryptOrder(String userId, String enData) {
+ //ProtocolRender render = pset.getProtocolReqRender("78");
+ Proto78 proto = new Proto78();
+
+ byte[] pOrgData = SYMUtil.base64EnData2DerEnDataC1C2C3(enData);
+
+ System.out.println("解密内部输出: " + Util.bytes2HexString(pOrgData));
+
+ // 填充数据
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ packet.put("data", data);
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("AlgorithmKey$option", 1);
+ data.put("infoData", pOrgData);
+ data.put("privateKeyTag", SYMUtil.genPrivateKeyMark(userId, SYMUtil.KT_ENCRYPT, "00000001"));
+ // 渲染发送
+ ByteBuffer bb = proto.rend(packet);
+ synchronized (this) {
+ // 响应解析
+ bb = syncRead(syncSend(bb));
+ }
+ //ProtocolParser parser = pset.getProtocolResParse();
+ Packet p = proto.parse(bb);
+ Map ret = p.toMap();
+ if (
+ !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
+ ) {
+ throw new SydApiException("包序号不匹配", -4);
+ }
+ ret = (Map) ret.get("data");
+ PacketSection error = (PacketSection) ret.get("error");
+ if (!"00".equals(error.getString())) {
+ throw new SydApiException(error.getInfo(), error.autoInt());
+ }
+
+ return ((PacketSection) ret.get("data")).getBytes();
+ }
+
public byte[] SM3HashSNaId(String sn, String userId, byte[] msg) {
return SM3Hash(null, sn, null, userId, msg);
}
diff --git a/src/test/java/com/sunyard/sydapi/example/ABCNorthBranch.java b/src/test/java/com/sunyard/sydapi/example/ABCNorthBranch.java
index ed969a9..8834e8f 100644
--- a/src/test/java/com/sunyard/sydapi/example/ABCNorthBranch.java
+++ b/src/test/java/com/sunyard/sydapi/example/ABCNorthBranch.java
@@ -39,9 +39,10 @@ public class ABCNorthBranch {
SM2PublicKey = api.SM2GetPublicKeyC(SM2PrivateKeyTag);
SM2PrivateKey = api.SM2GetPrivateKeyC(SM2PrivateKeyTag);
- SM4Key = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) api.readKey(SM4PrivateKeyTag).get("key"))));
+ SM4Key = new String((byte[]) api.readKey(SM4PrivateKeyTag).get("key"));
+
System.out.println("=========================================密钥获取完成=========================================");
}
diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
index 0a27935..be79b2e 100644
--- a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
+++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
@@ -776,6 +776,8 @@ public class TestAllMethods {
String index = "333333333333333300A00000001";
RetWrap retWrap = api.readKey(index);
printRetWrap(retWrap);
+
+ System.out.println("aaaaaaaa: " + new String((byte[]) retWrap.get("key")));
}
// 测试通过
@@ -932,9 +934,10 @@ public class TestAllMethods {
// String index = "1111111111111148";
// 0342000450420312F4ABAD98AA8EFC1F8F8204BD9E2F752C59C25A4025E675EDA5FB2337A449E00241EFA4A2F76A6C58D9834D6F0AB1164652E9C588E0EBD539C8ECB9EF
- // 1111111111111149 000 00000001
- String index = "1111111111111149";
- // 03420004080589A33A4DB304A3C48355761AC216B8BB5493966996E532B664A5B9CD8F1374F0DAACBF3F6D1F0E48E10DAA91889DB632FF4BE19D903502680D1AB56584D5
+ // 1111111111111151 000 00000001
+ String index = "1111111111111151";
+ // 034200048043AF118B45629857DB693105849B2617FED249D59DFD29BE9A891ADEE7441A2D8C62020953DAEF038184E0244310CF2123C507F26F5380FFECC8D53E79B24E
+ // 00010000BEF3ECEF9CC88ED5F1159F2B18DCFC648D9FF6A8D6F36516F0333B106805A9B30000000000000000000000000000000000000000000000000000000000000000
// SM2
RetWrap retWrap = api.SM2OrRSAGenKeyPair(1, index, 0);
@@ -1296,6 +1299,19 @@ public class TestAllMethods {
printRetWrap(retWrap1);
}
+ @Test
+ public void testDecryptDE4() {
+ String sn = "1004282452";
+
+ RetWrap retWrap = api.generateDEbyGS(sn, "00001111222233");
+ String CipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ String sessionKey = (String) retWrap.get(SydApi.RET_SESSION_KEY);
+ printRetWrap(retWrap);
+
+ RetWrap retWrap1 = api.decryptDE(sn, CipherKey);
+ printRetWrap(retWrap1);
+ }
+
// 测试通过
// 6C
@Test
@@ -1684,16 +1700,36 @@ public class TestAllMethods {
// 78
@Test
public void testSM2DecryptC() {
- String certId = "1111111111111122";
- String publicKey = "0342000469DE3847DD6A66DA96DB8F2DCFA32E10E680FF2EF4A592079E7C3A44320BB15084E7CA9782A39B6E28F07C04FE00D68958A2605921E71712D56C1E4435A39FA5";
- String orgData = "FFFFFFFFFFFFFFFF";
+ String certId = "1111111111111151";
+ String publicKey = "034200048043AF118B45629857DB693105849B2617FED249D59DFD29BE9A891ADEE7441A2D8C62020953DAEF038184E0244310CF2123C507F26F5380FFECC8D53E79B24E";
+ String orgData = "FFFFFFFFFFF1111111111FFFFF";
String s = api.SM2Encrypt(Util.hexString2Bytes(publicKey), orgData.getBytes());
+ System.out.println("加密后的数据: " + s);
+ byte[] pOrgData = SYMUtil.base64EnData2DerEnData(s);
+ System.out.println("加密后的数据解base64-2: " + Util.bytes2HexString(pOrgData));
+
byte[] bytes = api.SM2DecryptC(certId, s);
System.out.println("decData:" + new String(bytes));
}
+ // 测试通过
+ // 78
+ @Test
+ public void testSM2DecryptOrder() {
+ String certId = "1111111111111151";
+ String publicKey = "034200048043AF118B45629857DB693105849B2617FED249D59DFD29BE9A891ADEE7441A2D8C62020953DAEF038184E0244310CF2123C507F26F5380FFECC8D53E79B24E";
+ String orgData = "FfffffffffffffFfffffffffffffffff";
+ String s = api.SM2EncryptOrder(Util.hexString2Bytes(publicKey), orgData.getBytes());
+
+ System.out.println("加密后的数据: " + s);
+
+ byte[] bytes = api.SM2DecryptOrder(certId, s);
+
+ System.out.println("decData:" + new String(bytes));
+ }
+
// QQ
@Test
public void testSM2GetPublicKeyC() {
diff --git a/src/test/java/com/sunyard/sydapi/test/TestGSYH.java b/src/test/java/com/sunyard/sydapi/test/TestGSYH.java
index c9355cd..8235081 100644
--- a/src/test/java/com/sunyard/sydapi/test/TestGSYH.java
+++ b/src/test/java/com/sunyard/sydapi/test/TestGSYH.java
@@ -1,6 +1,7 @@
package com.sunyard.sydapi.test;
import com.sunyard.RetWrap;
+import com.sunyard.SydApi;
import com.sunyard.cert.X509;
import com.sunyard.proto.Util;
import org.junit.After;
@@ -11,6 +12,8 @@ import racal.sunyard.main.SydApi4j;
import java.io.IOException;
import java.util.Base64;
+import static com.sunyard.sydapi.util.PrintUtil.printRetWrap;
+
/**
* 甘肃银行数字货币
*/
@@ -26,10 +29,19 @@ public class TestGSYH {
public void before() {
// 通过设置debug的属性开启debug,如果不设置则默认不打开
System.setProperty("com.sunyard.sydapi4j.debug", "true");
- api = (SydApi4j) new SydApi4j().connect("192.168.0.66", 8889, null, 1000);
+ api = (SydApi4j) new SydApi4j().connect("61.164.40.82", 8889, null, 1000);
}
+ @After
+ public void after() {
+ try {
+ this.api.disconnect();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
@Test
public void test02() {
Base64.Encoder encoder = Base64.getEncoder();
@@ -38,24 +50,25 @@ public class TestGSYH {
// 2.
String data = "1111111111111111";
// 随机生成对称密钥,由指定的公钥加密生成数字信封
- RetWrap retWrap = api.generateDE(sn, (byte) 0x31);
- String sessionKey = (String) retWrap.get("SessionKey");
+ RetWrap retWrap = api.generateDEbyGS(sn, SydApi.ALG_SM4);
+ String sessionKey = (String) retWrap.get(SydApi.RET_SESSION_KEY);
// sm4加密账号等数据
- byte[] dataEnc = api.SYMEncryptData(3, sessionKey, data.getBytes());
+ byte[] dataEnc = api.SYMEncryptData(SydApi.NALG_SM4, sessionKey, data.getBytes());
// base64转码
byte[] dataEncBs64 = encoder.encode(dataEnc);
- // 将sm2加密后的数据进行base64转码
- String cipherKey = (String) retWrap.get("CipherKey");
- byte[] cipherKeyBs64 = encoder.encode(cipherKey.getBytes());
+ System.out.println("dataEncBs64: " + Util.bytes2HexString(dataEncBs64));
+ // 将sm2加密后的数据进行base64转码
+ String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ byte[] cipherKeyBs64 = encoder.encode(cipherKey.getBytes());
// 3.
// 报文正文
String msg = "12313146464564";
// 对报文正文签名(内部会计算hash)
- String msgSign = api.netSign(sn1, msg.getBytes());
+ String msgSign = api.netGSSign(sn1, msg.getBytes());
// base64转码
byte[] msgSignBs64 = encoder.encode(msgSign.getBytes());
@@ -65,31 +78,22 @@ public class TestGSYH {
// base64解码
byte[] msgSignB = decoder.decode(msgSignBs64);
// 对报文验签
- boolean b = api.netVerify(sn1, dataEncBs64, new String(msgSignB));
+ boolean b = api.netGSVerify(sn1, msg.getBytes(), new String(msgSignB));
System.out.println("验签结果: " + b);
// 8.
byte[] cipherKeyB = decoder.decode(cipherKeyBs64);
// 解密数字信封获取对称密钥
RetWrap retWrap1 = api.decryptDE(sn, new String(cipherKeyB));
- sessionKey = (String) retWrap1.get("SessionKey");
+ sessionKey = (String) retWrap1.get(SydApi.RET_SESSION_KEY);
// 9.
// 使用对称密钥解密报文
dataEnc = decoder.decode(dataEncBs64);
- byte[] bytes1 = api.SYMDecryptData(3, sessionKey, dataEnc);
+ byte[] bytes1 = api.SYMDecryptData(SydApi.NALG_SM4, sessionKey, dataEnc);
System.out.println("data: " + new String(bytes1));
}
- @After
- public void after() {
- try {
- this.api.disconnect();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
// 测试通过
// 8017
@Test
@@ -102,7 +106,7 @@ public class TestGSYH {
* @param nCertType 证书类型,0:签名证书, 1:加密证书
* @return base64 编码的证书
*/
- String s = api.GetX509CertFileBySN(sn2, 0);
+ String s = api.GetX509CertFileBySN(sn2, SydApi.FOR_SIGN);
System.out.println(s);
/**
@@ -115,34 +119,6 @@ public class TestGSYH {
System.out.println("证书主题DN: " + x509.getSubject());
}
- @Test
- public void testImportCert2() throws IOException {
-
- String cert2 = "-----BEGIN CERTIFICATE-----\n" +
- "MIIB4TCCAYSgAwIBAgIIPJMAAAAAACswDAYIKoEcz1UBg3UFADAmMQswCQYDVQQG\n" +
- "EwJDTjEXMBUGA1UEAwwOU3VueWFyZFNNMlJvb3QwHhcNMTcxMTE3MDIzMDUxWhcN\n" +
- "MjMwMTI1MDIzMDUxWjBZMQswCQYDVQQGEwJDTjELMAkGA1UECAwCWkoxCzAJBgNV\n" +
- "BAcMAkhaMQ4wDAYDVQQKDAVISkpZUzERMA8GA1UECwwIMDAwMDAwMDAxDTALBgNV\n" +
- "BAMMBDIyMjIwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAATxqegqlmc/lduzBaKR\n" +
- "EyeNuPf78RA3wfJuhAv8zymLwQ6doefs1Iul+kMOukhfwY9aEhVdqws34FZMm2vs\n" +
- "1+wXo2cwZTAOBgNVHQ8BAf8EBAMCAMAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYD\n" +
- "VR0jBBgwFoAU93/arv8hxtk6eq2g+6z+AqVO1cEwHQYDVR0OBBYEFHfjFl72707A\n" +
- "6s+YVuGvEuyvFWTMMAwGCCqBHM9VAYN1BQADSQAwRgIhALzg7+QW7RU4phv+4arE\n" +
- "v0IOeaA6dtR8VT4Bwin9oHTWAiEA9kLESGiYm8L5Htf7GBXgH+pk7BJ68clml41B\n" +
- "/ejZglI=\n" +
- "-----END CERTIFICATE-----";
-
- String organizationId = "00000000";
-
- /**
- * 上传指定证书到加密设备
- * @param certData 证书的字节数组
- * @param organizationId 机构号的字节数组
- * @return
- */
- RetWrap retWrap = api.importCert(Util.getSafeBytes(cert2), organizationId.getBytes());
- System.out.println(retWrap);
- }
@Test
public void testimportCertAddHT() {
@@ -202,45 +178,75 @@ public class TestGSYH {
System.out.println("证书公钥: " + Util.bytes2HexString(x509.getPubKey()));
}
+
+ // 测试通过
+ // 78
@Test
- public void test() {
- // 证书序号
- String sn = "1004282451";
- String data = "111";
+ public void testSM2DecryptC() {
+ String certId = "1111111111111151";
+ String publicKey = "034200048043AF118B45629857DB693105849B2617FED249D59DFD29BE9A891ADEE7441A2D8C62020953DAEF038184E0244310CF2123C507F26F5380FFECC8D53E79B24E";
+
+ String orgData = "FFFFFFFFFFFFFFFF";
+ String s = api.SM2Encrypt(Util.hexString2Bytes(publicKey), orgData.getBytes());
+
+ System.out.println("加密后的数据: " + s);
+ System.out.println("加密后的数据解base64: " + Util.bytes2HexString(Base64.getDecoder().decode(s)));
+
+ byte[] bytes = api.SM2DecryptC(certId, s);
+
+ System.out.println("decData:" + new String(bytes));
+ }
+
+ // 测试通过
+ // 78
+ @Test
+ public void testSM2DecryptOrder() {
+ String certId = "1111111111111151";
+ String publicKey = "034200048043AF118B45629857DB693105849B2617FED249D59DFD29BE9A891ADEE7441A2D8C62020953DAEF038184E0244310CF2123C507F26F5380FFECC8D53E79B24E";
+ String orgData = "FfffffffffffffFfffffffffffffffff";
/**
- * 用指定的证书私钥对指定的数据进行数字签名。
- * @param pCertSerial 输入。签名 X509 证书的序列号。
- * @param pOrgData 输入。 待签名的原始数据。
- * @return 签名数据(BASE64 编码)。
+ * 用指定的 SM2 公钥对指定的密文数据进行加密。
+ * 输出的sm2密文结构为C1C2C3格式
+ * @param publicKey 公钥钥串,DER 编码,HEX 格式。
+ * @param pOrgData 加密的数据。
+ * @return 加密的数据 base64 编码。
*/
- String s = api.netSign(sn, data.getBytes());
+ String s = api.SM2EncryptOrder(Util.hexString2Bytes(publicKey), orgData.getBytes());
+
+ System.out.println("加密后的数据: " + s);
/**
- * 用指定证书对指定的原始数据进行数字签名验证。
- * @param pCertSerial 输入。 签名 X509 证书的序列号。
- * @param pOrgData 输入。 待签名的原始数据。
- * @param pSignData 输入。 签名数据(BASE64 编码)。
- * @return true 表示验证正确;false 表示失败;
+ * 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
+ * 输入的sm2密文结构为C1C2C3格式
+ * @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
+ * @param enData 加密的数据,base64 编码。
+ * @return 明文数据。
*/
- // 12、对正文进行验签(内部会计算hash)
- boolean b = api.netVerify(sn, data.getBytes(), s);
- System.out.println(b);
+ byte[] bytes = api.SM2DecryptOrder(certId, s);
+ System.out.println("decData:" + new String(bytes));
+ }
+
+ @Test
+ public void testDecryptDE4() {
+ String sn = "1004282452";
- String sn1 = "1004282452";
/**
* 产生对称密钥,通过公钥加密生成网联格式的数字信封。
*
* @param certSerial 对*方 X509 证书的序列号。
- * @param nAlg 算法标识,0:AES,1:SM4
+ * @param orgCode 机构码
* @return RetWrap 包含 CipherKey, SessionKey, KCV
* CipherKey 公钥加密的会话密钥 ,BASE64 编码
* SessionKey 本地LMK 加密的会话密钥,HEX 格式, 本地 LMK 加密的会话密钥长度,HEX 格式(不包括第 1 个字符),一般为 33 个 Bytes。默认输入值为缓冲区的大小。
* KCV 会话密钥的检验值,HEX 格式,长度为 32H。
*/
- RetWrap retWrap = api.generateDE(sn1, (byte) 0x31);
- String CipherKey = (String) retWrap.get("CipherKey");
+ RetWrap retWrap = api.generateDEbyGS(sn, "00001111222233");
+ String CipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
+ String sessionKey = (String) retWrap.get(SydApi.RET_SESSION_KEY);
+ String kcv = (String) retWrap.get(SydApi.RET_KCV);
+ printRetWrap(retWrap);
/**
* 接收用私钥解密数字信封,还原对称密钥。
@@ -250,110 +256,38 @@ public class TestGSYH {
* @return RetWrap 包含 SessionKey KCV
* SessionKey 输出。 本地LMK 加密的会话密钥,格式为:密钥类型|密钥密文,比如:02|密钥密文
* KCV 会话密钥的检验值,HEX 格式,长度为 36H。
+ * orgCode 如果有机构码的话会返回机构码
*/
- // 13、解密数字信封获取对称密钥
- RetWrap rw = api.decryptDE(sn1, CipherKey);
- String sessionKey = (String) rw.get("SessionKey");
-
- /**
- * 用输入的会话密钥,对指定报文数据进行加密处理。填充模式为1
- *
- * @param nAlg 算法标识. 3:SM4。
- * @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
- * @param pINdata 要加密的报文明文。必须是 8 或16 的倍数。
- * @return 输出的报文密文, 长度为报文明文 + 16
- */
- byte[] bytes = api.SYMEncryptData(3, sessionKey, "1111111111111111".getBytes());
-
- /**
- * 用输入的会话密钥,对指定报文数据进行解密处理。填充模式为1
- *
- * @param nAlg 算法标识.3:SM4。
- * @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
- * @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数。
- * @return 输出的报文明文。
- */
- // 13、使用对称密钥解密敏感数据
- byte[] bytes1 = api.SYMDecryptData(3, sessionKey, bytes);
- System.out.println(new String(bytes1));
-
+ RetWrap retWrap1 = api.decryptDE(sn, CipherKey);
+ printRetWrap(retWrap1);
}
- // 签名验签流程
- @Test
- public void testNetGSSign() {
- // 本行的
- String sn = "10000000000000000000001042580423";
- String data = "111";
+ // =========================工具方法=====================
- /**
- * 用指定的证书私钥对指定的数据进行数字签名。
- * 最大签名原始数据为8161byte
- * @param publicKey 输入。公钥。
- * @param pCertSerial 输入。签名 X509 证书的序列号。
- * @param pOrgData 输入。 待签名的原始数据。
- * @return 签名数据(BASE64 编码)。
- */
- String sign = api.netGSSign(sn, data.getBytes());
- System.out.println("签名结果: " + sign);
-
- /**
- * 用指定证书对指定的原始数据进行数字签名验证。
- * @param publicKey 输入。公钥。
- * @param pCertSerial 输入。 签名 X509 证书的序列号。
- * @param pOrgData 输入。 待签名的原始数据。
- * @param pSignData 输入。 签名数据(BASE64 编码)。
- * @return true 表示验证正确;false 表示失败;
- */
- boolean b = api.netGSVerify(sn, data.getBytes(), sign);
- System.out.println("验签结果: " + b);
+ public static void printRetWrap(RetWrap rw) {
+ printRetWrap(rw, false);
}
+ /**
+ * 输出
+ * @param rw
+ */
+ public static void printRetWrap(RetWrap rw, boolean flag) {
+ for (String s : rw.keySet()) {
- @Test
- public void testVerify() {
-
- String orgData = "\n" +
- "\n" +
- " \n" +
- " \n" +
- " 20211231058043300311422380336000\n" +
- " 2021-12-31T14:22:38\n" +
- " \n" +
- " C1030131001288\n" +
- " \n" +
- " \n" +
- " C1175662000017\n" +
- " \n" +
- " \n" +
- " MT01\n" +
- " \n" +
- " C1175662000017\n" +
- " AT00\n" +
- " 983zGfqfC3O7xbgYwsW9TfRp1ddVT7vfaAAGhZ7Y7M0=\n" +
- " VbuPbl33/yi8OsQkme0kqZ0Tmvf8eJIyngC8CRyIk8E=\n" +
- " IT01\n" +
- " v1NPE/GPSooCXY4Z4RomtgDGpLxcm7RnF/VS16LEd3U=\n" +
- " G8DUftbIJTJpjrIgvoF3KQ==\n" +
- " SG01\n" +
- " \n" +
- " \n" +
- " C1030131001288\n" +
- " ZyBTxt3R/zN6AD7KqWotug==\n" +
- " WT01\n" +
- " WL01\n" +
- " \n" +
- " \n" +
- "";
-
- String sn = "10000000000000000000001042580423";
-
- String sign = "MEUCIGpByl+Q1uSLXVPHdRvPXufgGEru+kUDj13jBY68b3NrAiEA3WbN3tYTCK7GRIsfnVA+3jbGTYluKs/Xz+JZkFZ4tIM=";
-
- boolean b = api.netGSVerify(sn, orgData.getBytes(), sign);
- System.out.println("验签结果: " + b);
+ Object o = rw.get(s);
+ if (o instanceof String) {
+ System.out.println(s + ":" + o);
+ } else if (o instanceof byte[]) {
+ if (flag) {
+ System.out.println(s + ": " + Util.bytes2HexString((byte[]) o));
+ } else {
+ System.out.println(s + ": " + new String((byte[]) o));
+ }
+ } else {
+ System.out.println(s + ":" + o);
+ }
+ }
}
-
-
}
diff --git a/src/test/java/com/sunyard/sydapi/test/TestHT.java b/src/test/java/com/sunyard/sydapi/test/TestHT.java
index c6dd81c..4f0fcd5 100644
--- a/src/test/java/com/sunyard/sydapi/test/TestHT.java
+++ b/src/test/java/com/sunyard/sydapi/test/TestHT.java
@@ -40,20 +40,33 @@ public class TestHT {
@Test
public void testSM2ConfirmSessionKeyC() {
- String userId = "1111111111111149";
+ String userId = "1111111111111151";
+ String data = "12343242";
- String pk = api.SM2GetPublicKeyC(userId, 1);
+ // 通过用户id获取公钥
+ String pk = api.SM2GetPublicKeyC(userId, SydApi.FOR_ENCRYPT);
+ // 生成数字信封
RetWrap retWrap = api.SM2GenSessionKey(pk);
printRetWrap(retWrap);
String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY);
String sessionKey = (String) retWrap.get(SydApi.RET_SESSION_KEY);
String kcv = (String) retWrap.get(SydApi.RET_KCV);
+ // 使用生成的对称密钥加密数据
+ byte[] dataEnc = api.SYMEncryptData(SydApi.NALG_SM4, sessionKey, data.getBytes());
+
+
+
+ // 解密数字信封
RetWrap retWrap1 = api.SM2ConfirmSessionKeyC(userId, cipherKey);
printRetWrap(retWrap1);
sessionKey = (String) retWrap1.get(SydApi.RET_SESSION_KEY);
kcv = (String) retWrap1.get(SydApi.RET_KCV);
+
+ // 使用解密出来的对称密钥解密数据
+ byte[] bytes1 = api.SYMDecryptData(SydApi.NALG_SM4, sessionKey, dataEnc);
+ System.out.println("解密后的数据:" + new String(bytes1));
}
// 测试通过