Compare commits
No commits in common. "374ddad9bc006240747319bb7bf43db5b6a67f28" and "09a910006f4e9006f1730f65ecaa3efa9b53e7b4" have entirely different histories.
374ddad9bc
...
09a910006f
@ -16,6 +16,7 @@ import com.sunyard.constant.CertUsage;
|
|||||||
import com.sunyard.entity.ImportResult;
|
import com.sunyard.entity.ImportResult;
|
||||||
import com.sunyard.entity.MutiReturn7;
|
import com.sunyard.entity.MutiReturn7;
|
||||||
import com.sunyard.entity.Struct;
|
import com.sunyard.entity.Struct;
|
||||||
|
import com.sunyard.entity.TimeStats;
|
||||||
import com.sunyard.log.ILogFactory;
|
import com.sunyard.log.ILogFactory;
|
||||||
import com.sunyard.log.ILogger;
|
import com.sunyard.log.ILogger;
|
||||||
import com.sunyard.proto.Packet;
|
import com.sunyard.proto.Packet;
|
||||||
@ -46,11 +47,9 @@ import racal.sunyard.main.proto.*;
|
|||||||
|
|
||||||
import javax.security.auth.x500.X500Principal;
|
import javax.security.auth.x500.X500Principal;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.*;
|
||||||
import java.net.Socket;
|
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.net.SocketTimeoutException;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
@ -333,6 +332,10 @@ public class SydApi4j implements SydApi {
|
|||||||
byte[] publicKey,
|
byte[] publicKey,
|
||||||
byte[] orgData) {
|
byte[] orgData) {
|
||||||
|
|
||||||
|
if (SydApi.DATA_HASH == nOrgDataType) {
|
||||||
|
orgData = SM3Hash(Util.bytes2HexString(publicKey), orgData);
|
||||||
|
}
|
||||||
|
|
||||||
Proto74 proto = new Proto74();
|
Proto74 proto = new Proto74();
|
||||||
|
|
||||||
// 填充数据
|
// 填充数据
|
||||||
@ -2586,48 +2589,68 @@ public class SydApi4j implements SydApi {
|
|||||||
|
|
||||||
private ByteBuffer read(Socket socket) throws IOException {
|
private ByteBuffer read(Socket socket) throws IOException {
|
||||||
InputStream is = socket.getInputStream();
|
InputStream is = socket.getInputStream();
|
||||||
int d;
|
byte[] buf = new byte[2];
|
||||||
int high = is.read();
|
int offset = 0;
|
||||||
int low = is.read();
|
int remaining = 2;
|
||||||
int len = (high << 8) + low;
|
while (remaining > 0) {
|
||||||
|
int read = is.read(buf, offset, remaining);
|
||||||
|
if (read == -1) {
|
||||||
|
throw new EOFException("Expected 2 bytes, but reached end of stream after reading " + offset + " byte(s)");
|
||||||
|
}
|
||||||
|
offset += read;
|
||||||
|
remaining -= read;
|
||||||
|
}
|
||||||
|
int len = ((buf[0] & 0xFF) << 8) | (buf[1] & 0xFF);
|
||||||
|
|
||||||
len += 2;
|
len += 2;
|
||||||
|
|
||||||
if(debug){
|
if(debug){
|
||||||
print("H\t");
|
print("接收数据\t");
|
||||||
println(Integer.toHexString(high));
|
// print("H=");
|
||||||
print("L\t");
|
// print(Integer.toHexString(high));
|
||||||
println(Integer.toHexString(low));
|
// print("\tL=");
|
||||||
print("Len\t");
|
// print(Integer.toHexString(low));
|
||||||
|
print("\tLen=");
|
||||||
println(len);
|
println(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteBuffer bb = ByteBuffer.allocate(len);
|
ByteBuffer bb = ByteBuffer.allocate(len);
|
||||||
bb.put((byte) (high & 0xFF));
|
bb.put(buf);
|
||||||
|
// bb.put((byte) (high & 0xFF));
|
||||||
//println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (high & 0xFF)})));
|
//println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (high & 0xFF)})));
|
||||||
|
|
||||||
bb.put((byte) (low & 0xFF));
|
// bb.put((byte) (low & 0xFF));
|
||||||
//println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (low & 0xFF)})));
|
//println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (low & 0xFF)})));
|
||||||
|
|
||||||
|
// int d = 0;
|
||||||
|
// while (true) {
|
||||||
|
// d = is.read();
|
||||||
|
// if (-1 == d) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// bb.put((byte) (d & 0xFF));
|
||||||
|
//
|
||||||
|
// //println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (d & 0xFF)})));
|
||||||
|
//
|
||||||
|
// if (bb.position() == len) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
remaining = len - bb.position(); // 还需要读取的字节数
|
||||||
|
byte[] buffer = new byte[8192]; // 批量读取缓冲区
|
||||||
|
|
||||||
while (true) {
|
while (remaining > 0) {
|
||||||
d = is.read();
|
int toRead = Math.min(remaining, buffer.length);
|
||||||
if (-1 == d) {
|
int bytesRead = is.read(buffer, 0, toRead);
|
||||||
break;
|
if (bytesRead == -1) {
|
||||||
|
// 与原逻辑不同:这里抛异常,而不是静默退出
|
||||||
|
throw new EOFException("Unexpected end of stream; expected " + remaining + " more bytes");
|
||||||
}
|
}
|
||||||
|
bb.put(buffer, 0, bytesRead);
|
||||||
bb.put((byte) (d & 0xFF));
|
remaining -= bytesRead;
|
||||||
|
|
||||||
//println(String.format("%d %d %s",len, bb.position() -1, Util.bytes2HexString(new byte[]{(byte) (d & 0xFF)})));
|
|
||||||
|
|
||||||
if (bb.position() == len) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (null != builder && builder.isUseEBCDMode()) {
|
if (null != builder && builder.isUseEBCDMode()) {
|
||||||
// print("EBCD 数据: \t");
|
// print("EBCD 数据: \t");
|
||||||
@ -2662,8 +2685,10 @@ public class SydApi4j implements SydApi {
|
|||||||
ByteBuffer bb = read(socket);
|
ByteBuffer bb = read(socket);
|
||||||
return bb;
|
return bb;
|
||||||
|
|
||||||
|
} catch (EOFException e) {
|
||||||
|
throw new SydApiException("接收数据不完整", -21, e);
|
||||||
}catch (SocketTimeoutException e) {
|
}catch (SocketTimeoutException e) {
|
||||||
throw new SydApiException("接收数据超时", -2);
|
throw new SydApiException("接收数据超时", -2, e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -6834,19 +6859,19 @@ public class SydApi4j implements SydApi {
|
|||||||
ParamChecker.checkNotNull(publicKey, "publicKey");
|
ParamChecker.checkNotNull(publicKey, "publicKey");
|
||||||
ParamChecker.checkNotNull(pOrgData, "pOrgData");
|
ParamChecker.checkNotNull(pOrgData, "pOrgData");
|
||||||
|
|
||||||
final int CHUNK_SIZE = 63 * 1024; // 64 KB
|
final int CHUNK_SIZE = 62 * 1024; // 62 KB
|
||||||
int dataLen = pOrgData.length;
|
int dataLen = pOrgData.length;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
while (offset < dataLen) {
|
while (offset < dataLen) {
|
||||||
int len = Math.min(CHUNK_SIZE, dataLen - offset);
|
int len = Math.min(CHUNK_SIZE, dataLen - offset);
|
||||||
// 调用底层支持偏移量的加密方法
|
// 调用底层支持偏移量的加密方法
|
||||||
SYD_SM2Encrypt(1, publicKey, ByteBuffer.wrap(pOrgData, offset, len), offset);
|
SYD_SM2Encrypt(1, publicKey, ByteBuffer.wrap(pOrgData, offset, len), offset, len, dataLen);
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算
|
// 计算
|
||||||
SYD_SM2Encrypt(2, publicKey, null, 0);
|
SYD_SM2Encrypt(2, publicKey, null, 0, 0, dataLen);
|
||||||
|
|
||||||
// 取回
|
// 取回
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@ -6855,7 +6880,7 @@ public class SydApi4j implements SydApi {
|
|||||||
int isLast = 0;
|
int isLast = 0;
|
||||||
|
|
||||||
while (isLast != 1) {
|
while (isLast != 1) {
|
||||||
MutiReturn7 ret = SYD_SM2Encrypt(3, null, null, idx);
|
MutiReturn7 ret = SYD_SM2Encrypt(3, null, null, idx, 0, 0);
|
||||||
ByteBuffer bb = ret.getData();
|
ByteBuffer bb = ret.getData();
|
||||||
isLast = ret.getIsLast();
|
isLast = ret.getIsLast();
|
||||||
|
|
||||||
@ -6882,7 +6907,7 @@ public class SydApi4j implements SydApi {
|
|||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// 支持大包加解密
|
// 支持大包加解密
|
||||||
private MutiReturn7 SYD_SM2Encrypt(int dataType, byte[] publicKey, ByteBuffer pOrgData, int idx) {
|
private MutiReturn7 SYD_SM2Encrypt(int dataType, byte[] publicKey, ByteBuffer pOrgData, int idx, int inLen, int totalLen) {
|
||||||
// 参数检查
|
// 参数检查
|
||||||
ParamChecker.checkInRange(dataType, "dataType", 1, 3);
|
ParamChecker.checkInRange(dataType, "dataType", 1, 3);
|
||||||
|
|
||||||
@ -6901,18 +6926,18 @@ public class SydApi4j implements SydApi {
|
|||||||
bb.put("7F".getBytes());
|
bb.put("7F".getBytes());
|
||||||
bb.put((byte) dataType); // 数据包标志
|
bb.put((byte) dataType); // 数据包标志
|
||||||
if ( 2 == dataType ) { // 公钥
|
if ( 2 == dataType ) { // 公钥
|
||||||
bb.put(ByteUtil.shortToBytes((short) publicKey.length));
|
bb.put(ByteUtil.shortToBytes((short) publicKey.length, ByteOrder.BIG_ENDIAN) );
|
||||||
bb.put(publicKey);
|
bb.put(publicKey);
|
||||||
}
|
}
|
||||||
if ( 1 == dataType ) { // 数据
|
if ( 1 == dataType ) { // 数据
|
||||||
bb.put(ByteUtil.shortToBytes((short) pOrgData.limit()));
|
bb.put(com.sunyard.util.BytesUtil.unsignedShortToBytes(inLen, ByteOrder.BIG_ENDIAN));
|
||||||
bb.put(pOrgData);
|
bb.put(pOrgData);
|
||||||
bb.put(ByteUtil.shortToBytes((short)idx));
|
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 3 == dataType) { // 仅数据长度
|
if ( 3 == dataType) { // 仅数据长度
|
||||||
bb.put( ByteUtil.shortToBytes((short) (63*1024)) );
|
bb.put( ByteUtil.shortToBytes((short) (62*1024), ByteOrder.BIG_ENDIAN) );
|
||||||
bb.put( ByteUtil.shortToBytes((short)idx));
|
bb.put( ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6924,8 +6949,41 @@ public class SydApi4j implements SydApi {
|
|||||||
|
|
||||||
// 通信
|
// 通信
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
// 响应解析
|
int originalTimeout = -1;
|
||||||
|
boolean timeoutModified = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 仅当 dataType == 2 时才执行超时时间调整逻辑
|
||||||
|
if (false && dataType == 2) {
|
||||||
|
// 获取当前 Socket 超时时间(毫秒),可能为 -1(无限等待)或 0(立即超时)
|
||||||
|
originalTimeout = this.socket.getSoTimeout();
|
||||||
|
|
||||||
|
// 计算 totalLen 是 1MB 的多少倍(整数倍,如 2M→2,3M→3,4M→4)
|
||||||
|
int rate = totalLen / (1024 * 1024);
|
||||||
|
|
||||||
|
// 仅当倍数 >1 且原超时时间为正数时,才按比例放大超时时间
|
||||||
|
if (rate > 1 && originalTimeout > 0) {
|
||||||
|
int newTimeout = originalTimeout * rate;
|
||||||
|
this.socket.setSoTimeout(newTimeout);
|
||||||
|
timeoutModified = true; // 标记已修改,以便 finally 中恢复
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应解析(无论是否调整超时,都正常执行)
|
||||||
bb = syncRead(syncSend(bb));
|
bb = syncRead(syncSend(bb));
|
||||||
|
|
||||||
|
} catch (SocketException e) {
|
||||||
|
throw new SydApiException("socket 状态错误", -5, e);
|
||||||
|
} finally {
|
||||||
|
// 仅当超时时间被实际修改过时才恢复原值
|
||||||
|
if (timeoutModified) {
|
||||||
|
try {
|
||||||
|
this.socket.setSoTimeout(originalTimeout);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
// 恢复失败时可根据需要记录日志,此处忽略
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bb.flip();
|
bb.flip();
|
||||||
@ -6943,9 +7001,10 @@ public class SydApi4j implements SydApi {
|
|||||||
int isLast = bb.get();
|
int isLast = bb.get();
|
||||||
byte[] dataLenArr = new byte[2];
|
byte[] dataLenArr = new byte[2];
|
||||||
bb.get(dataLenArr);
|
bb.get(dataLenArr);
|
||||||
int dataLen = ByteUtil.bytesToInt(dataLenArr);
|
int dataLen = Short.toUnsignedInt(ByteUtil.bytesToShort(dataLenArr, ByteOrder.BIG_ENDIAN));
|
||||||
// byte[] data = new byte[dataLen];
|
// byte[] data = new byte[dataLen];
|
||||||
// bb.get(data);
|
// bb.get(data);
|
||||||
|
// 从返回数据中创建密文切片,此时不拷贝数据。
|
||||||
ByteBuffer slice = ByteBufferUtil.sliceAndConsume(bb, dataLen);
|
ByteBuffer slice = ByteBufferUtil.sliceAndConsume(bb, dataLen);
|
||||||
return new MutiReturn7(retCode, isLast, slice);
|
return new MutiReturn7(retCode, isLast, slice);
|
||||||
} else {
|
} else {
|
||||||
@ -6966,19 +7025,19 @@ public class SydApi4j implements SydApi {
|
|||||||
ParamChecker.checkNotNull(privateKey, "privateKey");
|
ParamChecker.checkNotNull(privateKey, "privateKey");
|
||||||
ParamChecker.checkNotNull(pCipherData, "pCipherData");
|
ParamChecker.checkNotNull(pCipherData, "pCipherData");
|
||||||
|
|
||||||
final int CHUNK_SIZE = 63 * 1024; // 63 KB,与加密保持一致
|
final int CHUNK_SIZE = 62 * 1024; // 62 KB,与加密保持一致
|
||||||
int dataLen = pCipherData.length;
|
int dataLen = pCipherData.length;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
// 1. 分块传入密文
|
// 1. 分块传入密文
|
||||||
while (offset < dataLen) {
|
while (offset < dataLen) {
|
||||||
int len = Math.min(CHUNK_SIZE, dataLen - offset);
|
int len = Math.min(CHUNK_SIZE, dataLen - offset);
|
||||||
SYD_SM2Decrypt(1, privateKey, ByteBuffer.wrap(pCipherData, offset, len), offset);
|
SYD_SM2Decrypt(1, privateKey, ByteBuffer.wrap(pCipherData, offset, len), offset, len, 0);
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 传入私钥,触发解密处理
|
// 2. 传入私钥,触发解密处理
|
||||||
SYD_SM2Decrypt(2, privateKey, null, 0);
|
SYD_SM2Decrypt(2, privateKey, null, 0, 0, dataLen);
|
||||||
|
|
||||||
// 3. 分块取回明文
|
// 3. 分块取回明文
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@ -6987,7 +7046,7 @@ public class SydApi4j implements SydApi {
|
|||||||
int isLast = 0;
|
int isLast = 0;
|
||||||
|
|
||||||
while (isLast != 1) {
|
while (isLast != 1) {
|
||||||
MutiReturn7 ret = SYD_SM2Decrypt(3, null, null, idx);
|
MutiReturn7 ret = SYD_SM2Decrypt(3, null, null, idx, 0, 0);
|
||||||
ByteBuffer bb = ret.getData();
|
ByteBuffer bb = ret.getData();
|
||||||
isLast = ret.getIsLast();
|
isLast = ret.getIsLast();
|
||||||
|
|
||||||
@ -7019,7 +7078,7 @@ public class SydApi4j implements SydApi {
|
|||||||
* @param idx 偏移量索引
|
* @param idx 偏移量索引
|
||||||
* @return MutiReturn7 包含返回码、isLast标志及数据片
|
* @return MutiReturn7 包含返回码、isLast标志及数据片
|
||||||
*/
|
*/
|
||||||
private MutiReturn7 SYD_SM2Decrypt(int dataType, byte[] privateKey, ByteBuffer pCipherData, int idx) {
|
private MutiReturn7 SYD_SM2Decrypt(int dataType, byte[] privateKey, ByteBuffer pCipherData, int idx, int inLen, int totalLen) {
|
||||||
ParamChecker.checkInRange(dataType, "dataType", 1, 3);
|
ParamChecker.checkInRange(dataType, "dataType", 1, 3);
|
||||||
|
|
||||||
// 估算缓存大小
|
// 估算缓存大小
|
||||||
@ -7036,17 +7095,18 @@ public class SydApi4j implements SydApi {
|
|||||||
bb.put((byte) dataType);
|
bb.put((byte) dataType);
|
||||||
|
|
||||||
if (dataType == 2) { // 私钥
|
if (dataType == 2) { // 私钥
|
||||||
bb.put(ByteUtil.shortToBytes((short) privateKey.length));
|
bb.put("999999999999999999999999999".getBytes());
|
||||||
|
bb.put(ByteUtil.shortToBytes((short) privateKey.length, ByteOrder.BIG_ENDIAN));
|
||||||
bb.put(privateKey);
|
bb.put(privateKey);
|
||||||
}
|
}
|
||||||
if (dataType == 1) { // 密文块
|
if (dataType == 1) { // 密文块
|
||||||
bb.put(ByteUtil.shortToBytes((short) pCipherData.limit()));
|
bb.put( com.sunyard.util.BytesUtil.unsignedShortToBytes(inLen, ByteOrder.BIG_ENDIAN) );
|
||||||
bb.put(pCipherData);
|
bb.put(pCipherData);
|
||||||
bb.put(ByteUtil.shortToBytes((short) idx));
|
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
|
||||||
}
|
}
|
||||||
if (dataType == 3) { // 请求明文块
|
if (dataType == 3) { // 请求明文块
|
||||||
bb.put(ByteUtil.shortToBytes((short) (63 * 1024)));
|
bb.put(ByteUtil.shortToBytes((short) (62 * 1024), ByteOrder.BIG_ENDIAN));
|
||||||
bb.put(ByteUtil.shortToBytes((short) idx));
|
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填写总长度(长度字段本身不包含在内)
|
// 填写总长度(长度字段本身不包含在内)
|
||||||
@ -7056,7 +7116,41 @@ public class SydApi4j implements SydApi {
|
|||||||
|
|
||||||
// 通信
|
// 通信
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
int originalTimeout = -1;
|
||||||
|
boolean timeoutModified = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 仅当 dataType == 2 时才执行超时时间调整逻辑
|
||||||
|
if (false && dataType == 2) {
|
||||||
|
// 获取当前 Socket 超时时间(毫秒),可能为 -1(无限等待)或 0(立即超时)
|
||||||
|
originalTimeout = this.socket.getSoTimeout();
|
||||||
|
|
||||||
|
// 计算 totalLen 是 1MB 的多少倍(整数倍,如 2M→2,3M→3,4M→4)
|
||||||
|
int rate = totalLen / (1024 * 1024);
|
||||||
|
|
||||||
|
// 仅当倍数 >1 且原超时时间为正数时,才按比例放大超时时间
|
||||||
|
if (rate > 1 && originalTimeout > 0) {
|
||||||
|
int newTimeout = originalTimeout * rate;
|
||||||
|
this.socket.setSoTimeout(newTimeout);
|
||||||
|
timeoutModified = true; // 标记已修改,以便 finally 中恢复
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应解析(无论是否调整超时,都正常执行)
|
||||||
bb = syncRead(syncSend(bb));
|
bb = syncRead(syncSend(bb));
|
||||||
|
|
||||||
|
} catch (SocketException e) {
|
||||||
|
throw new SydApiException("socket 状态错误", -5, e);
|
||||||
|
} finally {
|
||||||
|
// 仅当超时时间被实际修改过时才恢复原值
|
||||||
|
if (timeoutModified) {
|
||||||
|
try {
|
||||||
|
this.socket.setSoTimeout(originalTimeout);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
// 恢复失败时可根据需要记录日志,此处忽略
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bb.flip();
|
bb.flip();
|
||||||
@ -7073,7 +7167,7 @@ public class SydApi4j implements SydApi {
|
|||||||
int isLast = bb.get();
|
int isLast = bb.get();
|
||||||
byte[] dataLenArr = new byte[2];
|
byte[] dataLenArr = new byte[2];
|
||||||
bb.get(dataLenArr);
|
bb.get(dataLenArr);
|
||||||
int dataLen = ByteUtil.bytesToInt(dataLenArr);
|
int dataLen = Short.toUnsignedInt(ByteUtil.bytesToShort(dataLenArr, ByteOrder.BIG_ENDIAN));
|
||||||
ByteBuffer slice = ByteBufferUtil.sliceAndConsume(bb, dataLen);
|
ByteBuffer slice = ByteBufferUtil.sliceAndConsume(bb, dataLen);
|
||||||
return new MutiReturn7(retCode, isLast, slice);
|
return new MutiReturn7(retCode, isLast, slice);
|
||||||
} else {
|
} else {
|
||||||
@ -7081,6 +7175,149 @@ public class SydApi4j implements SydApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SM2 加密(支持大包分段)- 带时间统计
|
||||||
|
* @param publicKey 公钥字节数组
|
||||||
|
* @param pOrgData 明文数据
|
||||||
|
* @param timeStats 时间统计对象(输出参数)
|
||||||
|
* @return 加密后的密文
|
||||||
|
*/
|
||||||
|
public byte[] SYD_SM2Encrypt(byte[] publicKey, byte[] pOrgData, TimeStats timeStats){
|
||||||
|
ParamChecker.checkNotNull(publicKey, "publicKey");
|
||||||
|
ParamChecker.checkNotNull(pOrgData, "pOrgData");
|
||||||
|
|
||||||
|
final int CHUNK_SIZE = 62 * 1024; // 62 KB
|
||||||
|
int dataLen = pOrgData.length;
|
||||||
|
int offset = 0;
|
||||||
|
long sendStartTime = System.currentTimeMillis();
|
||||||
|
int sendCount = 0;
|
||||||
|
|
||||||
|
while (offset < dataLen) {
|
||||||
|
int len = Math.min(CHUNK_SIZE, dataLen - offset);
|
||||||
|
SYD_SM2Encrypt(1, publicKey, ByteBuffer.wrap(pOrgData, offset, len), offset, len, dataLen);
|
||||||
|
offset += len;
|
||||||
|
sendCount++;
|
||||||
|
}
|
||||||
|
long sendEndTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long computeStartTime = System.currentTimeMillis();
|
||||||
|
SYD_SM2Encrypt(2, publicKey, null, 0, 0, dataLen);
|
||||||
|
long computeEndTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long receiveStartTime = System.currentTimeMillis();
|
||||||
|
int idx = 0;
|
||||||
|
List<ByteBuffer> chunks = new ArrayList<>();
|
||||||
|
int totalLen = 0;
|
||||||
|
int isLast = 0;
|
||||||
|
int receiveCount = 0;
|
||||||
|
|
||||||
|
while (isLast != 1) {
|
||||||
|
MutiReturn7 ret = SYD_SM2Encrypt(3, null, null, idx, 0, 0);
|
||||||
|
ByteBuffer bb = ret.getData();
|
||||||
|
isLast = ret.getIsLast();
|
||||||
|
|
||||||
|
if (bb != null && bb.remaining() > 0) {
|
||||||
|
int remaining = bb.remaining();
|
||||||
|
chunks.add(bb);
|
||||||
|
totalLen += remaining;
|
||||||
|
idx += remaining;
|
||||||
|
receiveCount++;
|
||||||
|
} else if (isLast != 1) {
|
||||||
|
throw new RuntimeException("Empty chunk with isLast=0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long receiveEndTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
byte[] result = new byte[totalLen];
|
||||||
|
int offset2 = 0;
|
||||||
|
for (ByteBuffer chunk : chunks) {
|
||||||
|
int len = chunk.remaining();
|
||||||
|
chunk.get(result, offset2, len);
|
||||||
|
offset2 += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeStats != null) {
|
||||||
|
timeStats.setSendTime(sendEndTime - sendStartTime);
|
||||||
|
timeStats.setComputeTime(computeEndTime - computeStartTime);
|
||||||
|
timeStats.setReceiveTime(receiveEndTime - receiveStartTime);
|
||||||
|
timeStats.setSendCount(sendCount);
|
||||||
|
timeStats.setReceiveCount(receiveCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SM2 解密(支持大包分段)- 带时间统计
|
||||||
|
* @param privateKey 私钥字节数组
|
||||||
|
* @param pCipherData 密文数据
|
||||||
|
* @param timeStats 时间统计对象(输出参数)
|
||||||
|
* @return 解密后的明文
|
||||||
|
*/
|
||||||
|
public byte[] SYD_SM2Decrypt(byte[] privateKey, byte[] pCipherData, TimeStats timeStats) {
|
||||||
|
ParamChecker.checkNotNull(privateKey, "privateKey");
|
||||||
|
ParamChecker.checkNotNull(pCipherData, "pCipherData");
|
||||||
|
|
||||||
|
final int CHUNK_SIZE = 62 * 1024; // 62 KB,与加密保持一致
|
||||||
|
int dataLen = pCipherData.length;
|
||||||
|
int offset = 0;
|
||||||
|
long sendStartTime = System.currentTimeMillis();
|
||||||
|
int sendCount = 0;
|
||||||
|
|
||||||
|
while (offset < dataLen) {
|
||||||
|
int len = Math.min(CHUNK_SIZE, dataLen - offset);
|
||||||
|
SYD_SM2Decrypt(1, privateKey, ByteBuffer.wrap(pCipherData, offset, len), offset, len, 0);
|
||||||
|
offset += len;
|
||||||
|
sendCount++;
|
||||||
|
}
|
||||||
|
long sendEndTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long computeStartTime = System.currentTimeMillis();
|
||||||
|
SYD_SM2Decrypt(2, privateKey, null, 0, 0, dataLen);
|
||||||
|
long computeEndTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long receiveStartTime = System.currentTimeMillis();
|
||||||
|
int idx = 0;
|
||||||
|
List<ByteBuffer> chunks = new ArrayList<>();
|
||||||
|
int totalLen = 0;
|
||||||
|
int isLast = 0;
|
||||||
|
int receiveCount = 0;
|
||||||
|
|
||||||
|
while (isLast != 1) {
|
||||||
|
MutiReturn7 ret = SYD_SM2Decrypt(3, null, null, idx, 0, 0);
|
||||||
|
ByteBuffer bb = ret.getData();
|
||||||
|
isLast = ret.getIsLast();
|
||||||
|
|
||||||
|
if (bb != null && bb.remaining() > 0) {
|
||||||
|
chunks.add(bb);
|
||||||
|
totalLen += bb.remaining();
|
||||||
|
idx += bb.remaining();
|
||||||
|
receiveCount++;
|
||||||
|
} else if (isLast != 1) {
|
||||||
|
throw new RuntimeException("Empty plain chunk with isLast=0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long receiveEndTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
byte[] result = new byte[totalLen];
|
||||||
|
int offset2 = 0;
|
||||||
|
for (ByteBuffer chunk : chunks) {
|
||||||
|
int len = chunk.remaining();
|
||||||
|
chunk.get(result, offset2, len);
|
||||||
|
offset2 += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeStats != null) {
|
||||||
|
timeStats.setSendTime(sendEndTime - sendStartTime);
|
||||||
|
timeStats.setComputeTime(computeEndTime - computeStartTime);
|
||||||
|
timeStats.setReceiveTime(receiveEndTime - receiveStartTime);
|
||||||
|
timeStats.setSendCount(sendCount);
|
||||||
|
timeStats.setReceiveCount(receiveCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
|
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
|
||||||
@ -7508,7 +7745,7 @@ public class SydApi4j implements SydApi {
|
|||||||
|
|
||||||
// 填充数据
|
// 填充数据
|
||||||
PacketSN sn = PacketSN.gen();
|
PacketSN sn = PacketSN.gen();
|
||||||
final int packLen = 4064; // 2048
|
final int packLen = 8192; //4064 // 2048
|
||||||
int loop = msg.length / packLen;
|
int loop = msg.length / packLen;
|
||||||
if (msg.length % packLen > 0) {
|
if (msg.length % packLen > 0) {
|
||||||
loop++;
|
loop++;
|
||||||
@ -7564,7 +7801,7 @@ public class SydApi4j implements SydApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ByteBuffer bb = ByteBuffer.allocate(4 * 1024 + 128);
|
ByteBuffer bb = ByteBuffer.allocate(10 * 1024 );
|
||||||
|
|
||||||
byte[] ret = new byte[2];
|
byte[] ret = new byte[2];
|
||||||
bb.put(ret);
|
bb.put(ret);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user