From 954e5fb637389e1294408a2c6304a967ffa93e44 Mon Sep 17 00:00:00 2001 From: cheney Date: Thu, 21 Jul 2022 16:26:54 +0800 Subject: [PATCH] =?UTF-8?q?sm4=20=E9=95=BF=E6=95=B0=E6=8D=AE=E9=80=9F?= =?UTF-8?q?=E4=BC=A0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/racal/sunyard/main/SydApi4j.java | 89 ++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java index e44699a..cc078de 100644 --- a/src/main/java/racal/sunyard/main/SydApi4j.java +++ b/src/main/java/racal/sunyard/main/SydApi4j.java @@ -35,6 +35,15 @@ import java.util.*; public class SydApi4j implements SydApi { + // 数据包长度 + private final int MaxDataLenEachPack = 4064; + + // 批量数据包,单包数据长度 + // 加密 + private final int MaxDataLenEachBatchPackEn = 1024; + // 解密 + private final int MaxDataLenEachBatchPackDe = 1040; + private static boolean debug = false; private static long sTime = System.currentTimeMillis(); @@ -2062,6 +2071,82 @@ public class SydApi4j implements SydApi { return Util.bytes2HexString(mac); } + public byte[] SYD_SM4_LongData(int nAlg, String keyIndex, int fullmode, byte[] pcData, int iPkgNum) { + + if ( pcData.length > MaxDataLenEachPack ) { + throw new IllegalArgumentException("单包数据超长"); + } + + 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) (0x30 + iPkgNum) ); // 包序号 + bb.put( (byte) ( 0x30 + nAlg) ); // 密钥模式 + bb.put( (byte) ( 0x31) ); // ECB + bb.put( (byte) ( 0x30) ); // ZEK + + // 填充密钥 + bb.put( keyIndex.getBytes() ); + + bb.put( (byte) ( 0x30) ); // 输入消息类型二进制 + bb.put( (byte) ( 0x30) ); // 输出消息类型二进制 + + bb.put( (byte) ( 0x30 + fullmode) ); // 填充模式 + bb.put( "0000".getBytes() ); // 填充字符 + bb.put( (byte) ( 0x32) ); // 填充类型 + + // iv 暂未支持 + // P 长度暂未支持 + + + // 填充消息数据长度 + bb.put( String.format("%03X", pcData.length).getBytes() ); + + // 填充多个消息数据 + bb.put( pcData ); + + // 重新计算长度 + 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(); + + // 获取长度 + byte[] iLenArray = new byte[3]; + bb.get( iLenArray ); + int ilen = Integer.valueOf( new String( iLenArray ), 16 ); + + // 获取长度的数据 + byte[] d = new byte[ ilen ]; + bb.get(d); + return d; + } + public List SYMEncryptDecryptBatchData(int nAlg, String[] seesionKey, int fullmode, List pINdata) { int batchSize = pINdata.size(); @@ -2077,14 +2162,14 @@ public class SydApi4j implements SydApi { // 解密 for ( byte[]d : pINdata ) { if ( d.length > 1040 ) { - throw new IllegalArgumentException("批量单数数据超长 1040"); + throw new IllegalArgumentException("批量单数据超长 1040"); } } } else { // 加密 for ( byte[]d : pINdata ) { if ( d.length > 1024 ) { - throw new IllegalArgumentException("批量单数数据超长 1024"); + throw new IllegalArgumentException("批量单数据超长 1024"); } } }