diff --git a/pom.xml b/pom.xml index 197e9c8..e9c9cf8 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ com.sunyard sydapi4j - 1.12.20220915 + 1.13.20221212 org.apache.logging.log4j diff --git a/src/main/java/com/sunyard/sge/database/DataAndMac.java b/src/main/java/com/sunyard/sge/database/DataAndMac.java new file mode 100644 index 0000000..2ea21fc --- /dev/null +++ b/src/main/java/com/sunyard/sge/database/DataAndMac.java @@ -0,0 +1,27 @@ +package com.sunyard.sge.database; + +public class DataAndMac { + private byte[] data; + private String mac; + + public DataAndMac(byte[] data, String mac) { + this.data = data; + this.mac = mac; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } +} diff --git a/src/main/java/com/sunyard/sge/database/DataAndMacCheck.java b/src/main/java/com/sunyard/sge/database/DataAndMacCheck.java new file mode 100644 index 0000000..98eade0 --- /dev/null +++ b/src/main/java/com/sunyard/sge/database/DataAndMacCheck.java @@ -0,0 +1,28 @@ +package com.sunyard.sge.database; + +public class DataAndMacCheck { + private byte[] data; + private boolean macCheck; + + public DataAndMacCheck(byte[] data, boolean macCheck) { + this.data = data; + this.macCheck = macCheck; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + + public boolean getMacCheck() { + return macCheck; + } + + public void setMacCheck(boolean macCheck) { + this.macCheck = macCheck; + } +} diff --git a/src/main/java/com/sunyard/sge/database/SydApi.java b/src/main/java/com/sunyard/sge/database/SydApi.java index 7973d6f..e7a65c5 100644 --- a/src/main/java/com/sunyard/sge/database/SydApi.java +++ b/src/main/java/com/sunyard/sge/database/SydApi.java @@ -272,6 +272,48 @@ public interface SydApi { ); + /** + * 短数据加密并计算 MAC + * + * @param iEncKeyIndex:输入。加密所需要的密钥索引值 + * @param iMacKeyIndex:输入。计算mac所需要的密钥索引值 + * @param pcData: 输入。计算mac所需要的数据。 + * @return DataAndMac + * - data 密文 + * - mac值 (固定长度16字节)转HEX 字符串格式 + */ + DataAndMac SYD_SM4_EncryptAndMac_ShortData( + int iEncKeyIndex, + int iMacKeyIndex, + byte[] pcData + ); + + /** + * 短数据校验 MAC 并解密 + * @param iEncKeyIndex:输入。加密所需要的密钥索引值 + * @param iMacKeyIndex:输入。计算mac所需要的密钥索引值 + * @param pcData 输入。密文。 + * @param mac 输入。密文的 MAC。 + * @return 明文 + */ + byte[] SYD_SM4_CheckMacAndDecrypt_ShortData( + int iEncKeyIndex, + int iMacKeyIndex, + byte[] pcData, + String mac + ); + List SYD_SM4_EncryptAndMac_BatchData( + int[] iEncKeyIndex, + int[] iMacKeyIndex, + List pcData + ); + List SYD_SM4_CheckMacAndDecrypt_BatchData( + int[] iEncKeyIndex, + int[] iMacKeyIndex, + List pcData + ); + + public ISM4 initSM4(int iKeyIndex, int ende); public ISM3 initSM3(); diff --git a/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java b/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java index a88459a..06f8ee9 100644 --- a/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java +++ b/src/main/java/com/sunyard/sge/database/SydApiBaseFunction.java @@ -9,6 +9,7 @@ import com.sunyard.util.SYMUtil; import org.apache.logging.log4j.Logger; import racal.sunyard.main.SydApi4j; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -790,6 +791,70 @@ public class SydApiBaseFunction implements SydApi { } + @Override + public DataAndMac SYD_SM4_EncryptAndMac_ShortData(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData) { + byte[] enData = SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_ENC); + String mac = SYD_SM4Mac_ShortData(iMacKeyIndex, enData); + return new DataAndMac(enData, mac); + } + + @Override + public byte[] SYD_SM4_CheckMacAndDecrypt_ShortData(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData, String mac) { + boolean ret = SYD_SM4Mac_ShortData(iMacKeyIndex, pcData, mac); + if (!ret) { + throw new SydApiException("MAC 验证不通过", 90); + } + + return SYD_SM4_ShortData(iEncKeyIndex, pcData, Consts.ECB_DEC); + } + + @Override + public List SYD_SM4_EncryptAndMac_BatchData(int[] iEncKeyIndex, int[] iMacKeyIndex, List pcData) { + if (null == this.hsms || null == iMacKeyIndex || null == pcData) { + throw new SydApiException("输入内容为空",15); + } + if ( iEncKeyIndex.length != iMacKeyIndex.length || iEncKeyIndex.length != pcData.size() ) { + throw new SydApiException("密钥长度和数据长度不对应", 15); + } + + List enDatas = SYD_SM4_BatchData(iEncKeyIndex, pcData, Consts.ECB_ENC); + String[] macs = SYD_SM4Mac_BatchData(iMacKeyIndex, enDatas); + List ret = new ArrayList(); + for ( int i=0 ; i< enDatas.size() ; i++ ) { + DataAndMac dam = new DataAndMac(enDatas.get(i), macs[i]); + ret.add(dam); + } + return ret; + } + + @Override + public List SYD_SM4_CheckMacAndDecrypt_BatchData(int[] iEncKeyIndex, int[] iMacKeyIndex, List pcData) { + if (null == this.hsms || null == iMacKeyIndex || null == pcData) { + throw new SydApiException("输入内容为空",15); + } + if ( iEncKeyIndex.length != iMacKeyIndex.length || iEncKeyIndex.length != pcData.size() ) { + throw new SydApiException("密钥长度和数据长度不对应", 15); + } + + String[] macs = new String[pcData.size()]; + Listdatas = new ArrayList<>(pcData.size()); + for ( int i=0 ; i enData = SYD_SM4_BatchData(iEncKeyIndex, datas, Consts.ECB_DEC); + + Listret = new ArrayList<>(enData.size()); + for ( int i=0 ; i task = builder.getLongLinkWorks().fTask(new Callable() { + @Override + public DataAndMac call() throws Exception { + return builder.get().SYD_SM4_EncryptAndMac_ShortData(iEncKeyIndex, iMacKeyIndex, pcData); + } + }); + try { + return task.get(); + } catch (Exception e) { + throw new SydApiException("并行任务执行失败", 0xC101, e); + } + } + + @Override + public byte[] SYD_SM4_CheckMacAndDecrypt_ShortData(int iEncKeyIndex, int iMacKeyIndex, byte[] pcData, String mac) { + FutureTask task = builder.getLongLinkWorks().fTask(new Callable() { + @Override + public byte[] call() throws Exception { + return builder.get().SYD_SM4_CheckMacAndDecrypt_ShortData(iEncKeyIndex, iMacKeyIndex, pcData, mac); + } + }); + try { + return task.get(); + } catch (Exception e) { + throw new SydApiException("并行任务执行失败", 0xC101, e); + } + } + + @Override + public List SYD_SM4_EncryptAndMac_BatchData(int[] iEncKeyIndex, int[] iMacKeyIndex, List pcData) { + FutureTask> task = builder.getLongLinkWorks().fTask(new Callable>() { + @Override + public List call() throws Exception { + return builder.get().SYD_SM4_EncryptAndMac_BatchData(iEncKeyIndex, iMacKeyIndex, pcData); + } + }); + try { + return task.get(); + } catch (Exception e) { + throw new SydApiException("并行任务执行失败", 0xC101, e); + } + } + + @Override + public List SYD_SM4_CheckMacAndDecrypt_BatchData(int[] iEncKeyIndex, int[] iMacKeyIndex, List pcData) { + FutureTask> task = builder.getLongLinkWorks().fTask(new Callable>() { + @Override + public List call() throws Exception { + return builder.get().SYD_SM4_CheckMacAndDecrypt_BatchData(iEncKeyIndex, iMacKeyIndex, pcData); + } + }); + try { + return task.get(); + } catch (Exception e) { + throw new SydApiException("并行任务执行失败", 0xC101, e); + } + } + @Override public ISM4 initSM4(int iKeyIndex, int ende) { return new SydSM4(this, iKeyIndex, ende); diff --git a/src/test/java/sample/Encrypt.java b/src/test/java/sample/Encrypt.java index 00b5f7f..60d2a8d 100644 --- a/src/test/java/sample/Encrypt.java +++ b/src/test/java/sample/Encrypt.java @@ -1,11 +1,7 @@ package sample; -import com.sunyard.RetWrap; import com.sunyard.SydApi; import com.sunyard.proto.Util; -import com.sunyard.sge.database.SydApi4Database; -import com.sunyard.sge.database.SydApiBaseFunction; -import com.sunyard.sge.database.SydApiBuilder; import racal.sunyard.main.SydApi4j; public class Encrypt { @@ -20,14 +16,15 @@ public class Encrypt { * **/ String pk = api.SM2GetPublicKeyC("4444444444444444", 1); System.out.println("pk=" + pk); + // eg. 公钥格式 034200040675634F7E262715A0625FB2FBA62F947A8FA3318E5294DCA0829D2673F32022360B9E68BB419605341BED596097624D8F0DE5238CA3B2CF4C1BBBC21F6671B6 byte[] pkBytes = Util.hexString2Bytes(pk); /** * SYD_SM2_Encrypt SM2公钥加密 * 参数1:publicKey 传公钥 * 参数2:pOrgData 传加密数据 * **/ - byte[] sm2 = api.SYD_SM2_Encrypt(pkBytes ,new byte[100]); + byte[] sm2 = api.SYD_SM2_Encrypt(pkBytes, new byte[100]); String sm2Hex = Util.bytes2HexString(sm2); - System.out.println(sm2Hex); + System.out.println("密文(DER)="+ sm2Hex); } } diff --git a/src/test/java/test/EncryptAndMac.java b/src/test/java/test/EncryptAndMac.java new file mode 100644 index 0000000..bb8d924 --- /dev/null +++ b/src/test/java/test/EncryptAndMac.java @@ -0,0 +1,85 @@ +package test; + +import com.google.common.collect.Lists; +import com.sunyard.sge.database.*; +import org.junit.Assert; + +import java.util.Arrays; +import java.util.List; + +public class EncryptAndMac { + + public static void main(String[] args) { + + // 路径要以 / 或 \\ 结尾表示目录 + + String[] pcipList = {"172.1.41.216", "172.1.41.129"}; + int[] iportList = {8080, 8889}; + SydApi api = new SydApi4Database(); + try { + + api.SYD_Short_Connect_Ex(pcipList, iportList, 1000, 1000); + + // 密钥索引 + int keyEncIdx = 0; + + int keyMacIdx = 1; + + // 测试数据 + byte[] data = new byte[16]; + + + // 短数据 + DataAndMac ret = api.SYD_SM4_EncryptAndMac_ShortData(keyEncIdx, keyMacIdx, data); + byte[] deData = api.SYD_SM4_CheckMacAndDecrypt_ShortData(keyEncIdx, keyMacIdx, ret.getData(), ret.getMac()); + + if (Arrays.equals( data, deData ) ) { + System.out.println("短数据加密并计算 MAC - 测试通过"); + } else { + System.out.println("短数据加密并计算 MAC - 测试失败"); + } + + + // 批量短数据 + Listdata2 = Lists.newArrayList( + new byte[8], + new byte[500], + new byte[512] + ); + + + List ret2 = api.SYD_SM4_EncryptAndMac_BatchData( + new int[] {keyEncIdx, keyEncIdx, keyEncIdx}, + new int[] {keyMacIdx, keyMacIdx, keyMacIdx}, + data2 + ); + + ListdeDatas = api.SYD_SM4_CheckMacAndDecrypt_BatchData( + new int[] {keyEncIdx, keyEncIdx, keyEncIdx}, + new int[] {keyMacIdx, keyMacIdx, keyMacIdx}, + ret2 + ); + + for (int i=0; i< deDatas.size(); i++){ + byte[] d1 = data2.get(i); + DataAndMacCheck d2 = deDatas.get(i); + + if (! d2.getMacCheck() ) { + System.out.println("批量短数据加密并计算 MAC 验证失败 - 测试失败"); + return; + } + if (! Arrays.equals( d1, d2.getData() ) ) { + System.out.println("批量短数据加密并计算 MAC - 测试失败"); + return; + } + } + + System.out.println("批量短数据加密并计算 MAC - 测试通过"); + + } finally { + if (null != api) { + api.SYD_Disconnect_Ex(); + } + } + } +} diff --git a/src/test/java/test/PrefTest.java b/src/test/java/test/PrefTest.java index 7583c16..241e62d 100644 --- a/src/test/java/test/PrefTest.java +++ b/src/test/java/test/PrefTest.java @@ -1,6 +1,5 @@ package test; -import com.sunyard.proto.Util; import com.sunyard.sge.database.Consts; import com.sunyard.sge.database.SydApi; import com.sunyard.sge.database.SydApi4Database; diff --git a/说明.txt b/说明.txt index 33b1f13..7067de5 100644 --- a/说明.txt +++ b/说明.txt @@ -1,3 +1,15 @@ +SydApi - 接口 +SydApiBaseFunction - 主要用于长连接,由 Pool 创建。 +SydApi4Database - 主要用于短连接,继承自 SydApiBaseFunction + + + + +sydapi4j-1.0.20220906.jar +性能改动查看 + + + - doc 文档 - sample 示例代码 - jar