fix 长度问题
This commit is contained in:
parent
914ba8eee5
commit
d1c8201f98
@ -91,7 +91,7 @@ public final class ParamChecker {
|
|||||||
* @throws IllegalArgumentException 如果 str 为 null 或仅包含空白字符
|
* @throws IllegalArgumentException 如果 str 为 null 或仅包含空白字符
|
||||||
*/
|
*/
|
||||||
public static String checkNotBlank(String str, String paramName) {
|
public static String checkNotBlank(String str, String paramName) {
|
||||||
if (str == null || str.isBlank()) {
|
if (str == null || !str.trim().isEmpty()) {
|
||||||
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null、空字符串或仅包含空白字符");
|
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null、空字符串或仅包含空白字符");
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
|||||||
@ -6791,6 +6791,8 @@ public class SydApi4j implements SydApi {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData) {
|
public String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData) {
|
||||||
Proto77 proto = new Proto77();
|
Proto77 proto = new Proto77();
|
||||||
@ -6917,10 +6919,8 @@ public class SydApi4j implements SydApi {
|
|||||||
// 重新计算长度
|
// 重新计算长度
|
||||||
int len = bb.position();
|
int len = bb.position();
|
||||||
len -= 2;
|
len -= 2;
|
||||||
byte[] lenArray = new byte[2];
|
bb.put(0, (byte) ((len >> 8) & 0xFF)); // 覆盖开头的两个占位字节
|
||||||
lenArray[0] = (byte) ((len >> 8) & 0xFF);
|
bb.put(1, (byte) (len & 0xFF)); // 覆盖开头的两个占位字节
|
||||||
lenArray[1] = (byte) (len & 0xFF);
|
|
||||||
bb.put(lenArray);
|
|
||||||
|
|
||||||
// 通信
|
// 通信
|
||||||
synchronized (this) {
|
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
|
@Override
|
||||||
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
|
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
|
||||||
Proto77 proto = new Proto77();
|
Proto77 proto = new Proto77();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user