From dd63df5abb22b2da4bdddb237e656d627a4460aa Mon Sep 17 00:00:00 2001 From: cheney Date: Tue, 12 Jul 2022 20:12:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=B9=E9=87=8F=E5=8A=A0?= =?UTF-8?q?=E5=AF=86=E8=A7=A3=E5=AF=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../java/com/sunyard/inf/SydCryptionApi.java | 4 + .../java/racal/sunyard/main/SydApi4j.java | 115 +++++++++++++++++- .../sunyard/sydapi/test/TestBatchData.java | 29 +++++ 4 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/sunyard/sydapi/test/TestBatchData.java diff --git a/pom.xml b/pom.xml index b812d9f..fa01e99 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.sunyard sydapi4j - 1.0.20220402 + 1.0.20220712 jar sydapi4j diff --git a/src/main/java/com/sunyard/inf/SydCryptionApi.java b/src/main/java/com/sunyard/inf/SydCryptionApi.java index 20c2a6e..7a35f4d 100644 --- a/src/main/java/com/sunyard/inf/SydCryptionApi.java +++ b/src/main/java/com/sunyard/inf/SydCryptionApi.java @@ -3,6 +3,7 @@ package com.sunyard.inf; import com.sunyard.RetWrap; import java.io.UnsupportedEncodingException; +import java.util.List; /** * 对称加解密相关接口 @@ -265,6 +266,9 @@ interface SydSYMApi { */ byte[] SYMEncryptData(int nAlg, String seesionKey, int fullmode, byte[] pINdata); + + List SYMEncryptDecryptBatchData(int nAlg, String[] seesionKey, int fullmode, List pINdata); + /** * 用输入的会话密钥,对指定报文数据进行加密处理。 * diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java index 4f25bd6..5df8a00 100644 --- a/src/main/java/racal/sunyard/main/SydApi4j.java +++ b/src/main/java/racal/sunyard/main/SydApi4j.java @@ -1165,6 +1165,7 @@ public class SydApi4j implements SydApi { try { socket.getOutputStream().write(buff); + socket.getOutputStream().flush(); } catch (IOException e) { e.printStackTrace(); } @@ -1969,7 +1970,119 @@ public class SydApi4j implements SydApi { data.put("msg", pInData); packet.put("data", data); - return repackEncrypt(packet); + return repackEncrypt( packet ); + } + + + public List SYMEncryptDecryptBatchData(int nAlg, String[] seesionKey, int fullmode, List pINdata) { + + int batchSize = pINdata.size(); + if ( batchSize < 1 || batchSize > 10 ) { + throw new IllegalArgumentException("批量数量错误"); + } + + if ( seesionKey.length != pINdata.size() ) { + throw new IllegalArgumentException("密钥和数据数量不匹配"); + } + + if ( 0x0 != (byte) (nAlg & 0x1) ){ + // 解密 + for ( byte[]d : pINdata ) { + if ( d.length > 1040 ) { + throw new IllegalArgumentException("批量单数数据超长 1040"); + } + } + } else { + // 加密 + for ( byte[]d : pINdata ) { + if ( d.length > 1024 ) { + throw new IllegalArgumentException("批量单数数据超长 1024"); + } + } + } + + ByteBuffer bb = ByteBuffer.allocate(10 * 1024); + PacketSN sn = PacketSN.gen(); + bb.put( new byte[2] ); + bb.put( sn.getSn().array() ); + bb.put( "E0".getBytes() ); + bb.put( (byte) 0x34 ); // 批量加解密 + bb.put( (byte) batchSize ); // 批量数 + bb.put( (byte) ( 0x30 + nAlg) ); // 密钥模式 + bb.put( (byte) ( 0x31) ); // ECB + bb.put( (byte) ( 0x30) ); // ZEK + + // 填充多个密钥 + for ( String key : seesionKey ) { + bb.put( key.getBytes() ); + } + + bb.put( (byte) ( 0x30) ); // 输入消息类型二进制 + bb.put( (byte) ( 0x30) ); // 输出消息类型二进制 + + bb.put( (byte) ( 0x30 + fullmode) ); // 填充模式 + bb.put( "0000".getBytes() ); // 填充字符 + bb.put( (byte) ( 0x32) ); // 填充类型 + + // iv 暂未支持 + // P 长度暂未支持 + + + // 填充多个消息数据长度 + for ( byte[] data : pINdata ) { + bb.put( String.format("%03X", data.length).getBytes() ); + } + + // 填充多个消息数据 + for ( byte[] data : pINdata ) { + bb.put( data ); + } + + // 重新计算长度 + int len = bb.position(); + len -= 2; + byte[] lenArray = new byte[ 2 ]; + lenArray[0] = (byte)((len >> 8) & 0xFF); + lenArray[1] = (byte)( len & 0xFF); + + bb.put( 0, (byte)((len >> 8) & 0xFF) ); + bb.put( 1, (byte)( len & 0xFF) ); + + // 通信 + synchronized (this) { + // 响应解析 + bb = syncRead(syncSend(bb)); + } + + bb.flip(); + bb.position( 12 ); + byte[] code = new byte[2]; + bb.get( code ); + + int retCode = Integer.valueOf( new String( code ) ); + if ( 0 != retCode ) { + throw new SydApiException( retCode ); + } + + // 跳过输出模式 + bb.get(); + + // 获取 N 个长度 + int[] lens = new int[ batchSize ]; + for ( int i = 0; i < batchSize; i++ ){ + byte[] iLenArray = new byte[3]; + bb.get( iLenArray ); + lens[ i ] = Integer.valueOf( new String( iLenArray ), 16 ); + } + + Listret = new ArrayList(); + // 获取 N 个长度的数据 + for ( int l : lens ) { + byte[] d = new byte[ l ]; + bb.get(d); + ret.add( d ); + } + return ret; } diff --git a/src/test/java/com/sunyard/sydapi/test/TestBatchData.java b/src/test/java/com/sunyard/sydapi/test/TestBatchData.java new file mode 100644 index 0000000..c14d640 --- /dev/null +++ b/src/test/java/com/sunyard/sydapi/test/TestBatchData.java @@ -0,0 +1,29 @@ +package com.sunyard.sydapi.test; + + +import com.sunyard.proto.Util; +import racal.sunyard.main.SydApi4j; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class TestBatchData { + public static void main(String[] args) throws UnsupportedEncodingException { + + System.setProperty("com.sunyard.sydapi4j.debug", "true"); + SydApi4j.SYD_Set_Parameter_HA("unkown", "192.168.0.200", 8889, 3000); + + SydApi4j api = (SydApi4j) new SydApi4j();//.connect("wuyong.fullstack.club" , 8889, null,1000); + + + String[] keys = new String[]{"SK000000000000000000A00000000"}; + List pINdata = new ArrayList(); + pINdata.add("12345678".getBytes()); + + List datas = api.SYMEncryptDecryptBatchData(0x8, keys, 1, pINdata); + +// boolean pass = api.SM2Verify( 1, Util.hexString2Bytes(pk), Util.hexString2Bytes(inHexData), sign ); + } +}