Merge remote-tracking branch 'honor3/dev-V2.01' into dev-V2.01

# Conflicts:
#	src/main/java/racal/sunyard/main/SydApi4j.java
This commit is contained in:
cheney 2026-06-10 10:32:54 +08:00
commit 374ddad9bc

View File

@ -16,7 +16,6 @@ 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;
@ -52,7 +51,6 @@ import java.net.Socket;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.SocketTimeoutException; 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;
@ -335,10 +333,6 @@ 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();
// 填充数据 // 填充数据
@ -2592,69 +2586,49 @@ 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();
byte[] buf = new byte[2]; int d;
int offset = 0; int high = is.read();
int remaining = 2; int low = is.read();
while (remaining > 0) { int len = (high << 8) + low;
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("接收数据\t"); print("H\t");
// print("H="); println(Integer.toHexString(high));
// print(Integer.toHexString(high)); print("L\t");
// print("\tL="); println(Integer.toHexString(low));
// print(Integer.toHexString(low)); print("Len\t");
print("\tLen=");
println(len); println(len);
} }
ByteBuffer bb = ByteBuffer.allocate(len); ByteBuffer bb = ByteBuffer.allocate(len);
bb.put(buf); bb.put((byte) (high & 0xFF));
// 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 (remaining > 0) { while (true) {
int toRead = Math.min(remaining, buffer.length); d = is.read();
int bytesRead = is.read(buffer, 0, toRead); if (-1 == d) {
if (bytesRead == -1) { break;
// 与原逻辑不同这里抛异常而不是静默退出 }
throw new EOFException("Unexpected end of stream; expected " + remaining + " more bytes");
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;
} }
bb.put(buffer, 0, bytesRead);
remaining -= bytesRead;
} }
if (null != builder && builder.isUseEBCDMode()) { if (null != builder && builder.isUseEBCDMode()) {
// print("EBCD 数据: \t"); // print("EBCD 数据: \t");
// println(Util.bytes2HexString(bb.array())); // println(Util.bytes2HexString(bb.array()));
@ -2688,10 +2662,8 @@ public class SydApi4j implements SydApi {
ByteBuffer bb = read(socket); ByteBuffer bb = read(socket);
return bb; return bb;
} catch (EOFException e) { } catch (SocketTimeoutException e) {
throw new SydApiException("接收数据不完整", -21, e); throw new SydApiException("接收数据超时", -2);
}catch (SocketTimeoutException e) {
throw new SydApiException("接收数据超时", -2, e);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -6929,18 +6901,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, ByteOrder.BIG_ENDIAN) ); bb.put(ByteUtil.shortToBytes((short) publicKey.length));
bb.put(publicKey); bb.put(publicKey);
} }
if ( 1 == dataType ) { // 数据 if ( 1 == dataType ) { // 数据
bb.put(ByteUtil.shortToBytes((short) pOrgData.limit(), ByteOrder.BIG_ENDIAN)); bb.put(ByteUtil.shortToBytes((short) pOrgData.limit()));
bb.put(pOrgData); bb.put(pOrgData);
bb.put(ByteUtil.intToBytes(idx)); bb.put(ByteUtil.shortToBytes((short)idx));
} }
if ( 3 == dataType) { // 仅数据长度 if ( 3 == dataType) { // 仅数据长度
bb.put( ByteUtil.shortToBytes((short) (63*1024), ByteOrder.BIG_ENDIAN) ); bb.put( ByteUtil.shortToBytes((short) (63*1024)) );
bb.put( ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN)); bb.put( ByteUtil.shortToBytes((short)idx));
} }
@ -6971,7 +6943,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.bytesToShort(dataLenArr, ByteOrder.BIG_ENDIAN); int dataLen = ByteUtil.bytesToInt(dataLenArr);
// 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);
@ -7064,18 +7036,17 @@ public class SydApi4j implements SydApi {
bb.put((byte) dataType); bb.put((byte) dataType);
if (dataType == 2) { // 私钥 if (dataType == 2) { // 私钥
bb.put("999999999999999999999999999".getBytes()); bb.put(ByteUtil.shortToBytes((short) privateKey.length));
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(), ByteOrder.BIG_ENDIAN)); bb.put(ByteUtil.shortToBytes((short) pCipherData.limit()));
bb.put(pCipherData); bb.put(pCipherData);
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN)); bb.put(ByteUtil.shortToBytes((short) idx));
} }
if (dataType == 3) { // 请求明文块 if (dataType == 3) { // 请求明文块
bb.put(ByteUtil.shortToBytes((short) (63 * 1024), ByteOrder.BIG_ENDIAN)); bb.put(ByteUtil.shortToBytes((short) (63 * 1024)));
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN)); bb.put(ByteUtil.shortToBytes((short) idx));
} }
// 填写总长度长度字段本身不包含在内 // 填写总长度长度字段本身不包含在内
@ -7102,7 +7073,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.bytesToShort(dataLenArr, ByteOrder.BIG_ENDIAN); int dataLen = ByteUtil.bytesToInt(dataLenArr);
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 {
@ -7110,149 +7081,6 @@ 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) {
@ -7680,7 +7508,7 @@ public class SydApi4j implements SydApi {
// 填充数据 // 填充数据
PacketSN sn = PacketSN.gen(); PacketSN sn = PacketSN.gen();
final int packLen = 8192; //4064 // 2048 final int packLen = 4064; // 2048
int loop = msg.length / packLen; int loop = msg.length / packLen;
if (msg.length % packLen > 0) { if (msg.length % packLen > 0) {
loop++; loop++;
@ -7736,7 +7564,7 @@ public class SydApi4j implements SydApi {
} }
ByteBuffer bb = ByteBuffer.allocate(10 * 1024 ); ByteBuffer bb = ByteBuffer.allocate(4 * 1024 + 128);
byte[] ret = new byte[2]; byte[] ret = new byte[2];
bb.put(ret); bb.put(ret);