fix 长度问题

This commit is contained in:
cheney 2026-05-29 16:44:04 +08:00
parent 914ba8eee5
commit d1c8201f98
2 changed files with 132 additions and 5 deletions

View File

@ -91,7 +91,7 @@ public final class ParamChecker {
* @throws IllegalArgumentException 如果 str null 或仅包含空白字符
*/
public static String checkNotBlank(String str, String paramName) {
if (str == null || str.isBlank()) {
if (str == null || !str.trim().isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null、空字符串或仅包含空白字符");
}
return str;

View File

@ -6791,6 +6791,8 @@ public class SydApi4j implements SydApi {
}
@Override
public String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData) {
Proto77 proto = new Proto77();
@ -6917,10 +6919,8 @@ public class SydApi4j implements SydApi {
// 重新计算长度
int len = bb.position();
len -= 2;
byte[] lenArray = new byte[2];
lenArray[0] = (byte) ((len >> 8) & 0xFF);
lenArray[1] = (byte) (len & 0xFF);
bb.put(lenArray);
bb.put(0, (byte) ((len >> 8) & 0xFF)); // 覆盖开头的两个占位字节
bb.put(1, (byte) (len & 0xFF)); // 覆盖开头的两个占位字节
// 通信
synchronized (this) {
@ -6955,6 +6955,133 @@ public class SydApi4j implements SydApi {
/**
* SM2 解密支持大包分段
* @param privateKey 私钥字节数组
* @param pCipherData 密文数据
* @return 解密后的明文
*/
public byte[] SYD_SM2Decrypt(byte[] privateKey, byte[] pCipherData) {
ParamChecker.checkNotNull(privateKey, "privateKey");
ParamChecker.checkNotNull(pCipherData, "pCipherData");
final int CHUNK_SIZE = 63 * 1024; // 63 KB与加密保持一致
int dataLen = pCipherData.length;
int offset = 0;
// 1. 分块传入密文
while (offset < dataLen) {
int len = Math.min(CHUNK_SIZE, dataLen - offset);
SYD_SM2Decrypt(1, privateKey, ByteBuffer.wrap(pCipherData, offset, len), offset);
offset += len;
}
// 2. 传入私钥触发解密处理
SYD_SM2Decrypt(2, privateKey, null, 0);
// 3. 分块取回明文
int idx = 0;
List<ByteBuffer> chunks = new ArrayList<>();
int totalLen = 0;
int isLast = 0;
while (isLast != 1) {
MutiReturn7 ret = SYD_SM2Decrypt(3, null, null, idx);
ByteBuffer bb = ret.getData();
isLast = ret.getIsLast();
if (bb != null && bb.remaining() > 0) {
chunks.add(bb);
totalLen += bb.remaining();
idx += bb.remaining();
} else if (isLast != 1) {
throw new RuntimeException("Empty plain chunk with isLast=0");
}
}
// 合并明文分片
byte[] result = new byte[totalLen];
int offset2 = 0;
for (ByteBuffer chunk : chunks) {
int len = chunk.remaining();
chunk.get(result, offset2, len);
offset2 += len;
}
return result;
}
/**
* 底层解密通信与加密结构对称魔法数改为 "7G"
* @param dataType 1-传入密文块2-传入私钥3-取明文块
* @param privateKey 私钥dataType=2时使用
* @param pCipherData 密文块dataType=1时使用
* @param idx 偏移量索引
* @return MutiReturn7 包含返回码isLast标志及数据片
*/
private MutiReturn7 SYD_SM2Decrypt(int dataType, byte[] privateKey, ByteBuffer pCipherData, int idx) {
ParamChecker.checkInRange(dataType, "dataType", 1, 3);
// 估算缓存大小
int buffLen = 4096;
if (dataType == 1) {
buffLen = pCipherData.limit() > 4096 ? 64 * 1024 : 5 * 1024;
}
ByteBuffer bb = ByteBuffer.allocate(buffLen);
PacketSN sn = PacketSN.gen();
bb.put(new byte[2]); // 占位后续填总长度
bb.put(sn.getSn().array());
bb.put("7G".getBytes()); // 魔法数改为 "7G"
bb.put((byte) dataType);
if (dataType == 2) { // 私钥
bb.put(ByteUtil.shortToBytes((short) privateKey.length));
bb.put(privateKey);
}
if (dataType == 1) { // 密文块
bb.put(ByteUtil.shortToBytes((short) pCipherData.limit()));
bb.put(pCipherData);
bb.put(ByteUtil.shortToBytes((short) idx));
}
if (dataType == 3) { // 请求明文块
bb.put(ByteUtil.shortToBytes((short) (63 * 1024)));
bb.put(ByteUtil.shortToBytes((short) idx));
}
// 填写总长度长度字段本身不包含在内
int len = bb.position() - 2;
bb.put(0, (byte) ((len >> 8) & 0xFF)); // 覆盖开头的两个占位字节
bb.put(1, (byte) (len & 0xFF)); // 覆盖开头的两个占位字节
// 通信
synchronized (this) {
bb = syncRead(syncSend(bb));
}
bb.flip();
bb.position(12); // 跳过前12字节头部固定
byte[] code = new byte[2];
bb.get(code);
int retCode = Integer.parseInt(new String(code));
if (retCode != 0) {
throw new SydApiException(retCode);
}
// dataType=3 时有数据返回
if (dataType == 3) {
int isLast = bb.get();
byte[] dataLenArr = new byte[2];
bb.get(dataLenArr);
int dataLen = ByteUtil.bytesToInt(dataLenArr);
ByteBuffer slice = ByteBufferUtil.sliceAndConsume(bb, dataLen);
return new MutiReturn7(retCode, isLast, slice);
} else {
return new MutiReturn7(retCode, 0, null);
}
}
@Override
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
Proto77 proto = new Proto77();