sm4 长数据速传接口

This commit is contained in:
cheney 2022-07-21 16:26:54 +08:00
parent 3abf5021a3
commit 954e5fb637

View File

@ -35,6 +35,15 @@ import java.util.*;
public class SydApi4j implements SydApi { 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 boolean debug = false;
private static long sTime = System.currentTimeMillis(); private static long sTime = System.currentTimeMillis();
@ -2062,6 +2071,82 @@ public class SydApi4j implements SydApi {
return Util.bytes2HexString(mac); 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<byte[]> SYMEncryptDecryptBatchData(int nAlg, String[] seesionKey, int fullmode, List<byte[]> pINdata) { public List<byte[]> SYMEncryptDecryptBatchData(int nAlg, String[] seesionKey, int fullmode, List<byte[]> pINdata) {
int batchSize = pINdata.size(); int batchSize = pINdata.size();
@ -2077,14 +2162,14 @@ public class SydApi4j implements SydApi {
// 解密 // 解密
for ( byte[]d : pINdata ) { for ( byte[]d : pINdata ) {
if ( d.length > 1040 ) { if ( d.length > 1040 ) {
throw new IllegalArgumentException("批量单数据超长 1040"); throw new IllegalArgumentException("批量单数据超长 1040");
} }
} }
} else { } else {
// 加密 // 加密
for ( byte[]d : pINdata ) { for ( byte[]d : pINdata ) {
if ( d.length > 1024 ) { if ( d.length > 1024 ) {
throw new IllegalArgumentException("批量单数据超长 1024"); throw new IllegalArgumentException("批量单数据超长 1024");
} }
} }
} }