Author SHA1 Message Date
cheney 10d9d1b0d6 优化通信 2026-06-02 17:58:02 +08:00
cheney b8322538e7 QN 指令长度错误 2026-06-02 16:26:54 +08:00
cheney 83802b6ef6 强制指定大端模式 2026-06-02 15:06:29 +08:00
cheney 9062a9c17c 测试代码整理 2026-06-01 17:57:23 +08:00
cheney 88f4bdf603 测试代码整理 2026-06-01 13:41:28 +08:00
cheney 385e77b766 调整协议,index 改为 4 字节。 2026-06-01 10:02:49 +08:00
cheney 5259876780 添加测试代码 2026-05-29 18:03:08 +08:00
cheney f7fa777677 添加一个性能测试模板 2026-05-29 17:18:36 +08:00
cheney 1439f4aa63 整理依赖 2026-05-29 17:00:56 +08:00
cheney d1c8201f98 fix 长度问题 2026-05-29 16:44:04 +08:00
cheney 914ba8eee5 添加大数据加密指令 2026-05-29 16:25:04 +08:00
24 changed files with 1126 additions and 396 deletions
+1
View File
@@ -14,3 +14,4 @@ src/test/java/com/sunyard/sydapi/sample/*.*
~$*
/pack/
/.logs/
/bin/
+2 -2
View File
@@ -50,8 +50,8 @@
</options>
</error>
<pk len="32" cn="公钥"></pk>
<sk len="160" cn="私钥"></sk>
<pk len="128" cn="公钥"></pk>
<sk len="64" cn="私钥"></sk>
</data>
+30
View File
@@ -0,0 +1,30 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0
http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>assembled-test-jar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!-- 打包主代码 -->
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<!-- 打包测试代码 -->
<fileSet>
<directory>${project.build.testOutputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<!-- 打包依赖的Jar包 -->
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
+12 -55
View File
@@ -4,7 +4,7 @@
<groupId>com.sunyard</groupId>
<artifactId>sydapi4j</artifactId>
<version>1.0.2022-SNAPSHOT</version>
<version>2.01</version>
<packaging>jar</packaging>
<name>sydapi4j</name>
@@ -32,7 +32,13 @@
<version>1.0.3</version>
<scope>test</scope>
</dependency>
<!-- JMeter Java Sampler 核心依赖 -->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.4.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sunyard</groupId>
@@ -50,8 +56,6 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
@@ -63,26 +67,16 @@
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.4.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.68</version>
<!-- <scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
<!-- <scope>provided</scope>-->
</dependency>
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
@@ -104,29 +98,6 @@
<artifactId>gson</artifactId>
<version>2.13.1</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.codehaus.groovy</groupId>-->
<!-- <artifactId>groovy-all</artifactId>-->
<!-- <version>2.4.15</version>-->
<!--&lt;!&ndash; <version>4.0.26</version>&ndash;&gt;-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>ch.qos.logback</groupId>-->
<!-- <artifactId>logback-classic</artifactId>-->
<!-- <version>1.3.15</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!--<dependency>-->
<!--<groupId>club.fullstack</groupId>-->
<!--<artifactId>serialize</artifactId>-->
<!--<version>[1.0.201806051035, 1.1.SNAPSHOT)</version>-->
<!--</dependency>-->
<!-- https://mvnrepository.com/artifact/com.github.wvengen/proguard-maven-plugin -->
<!-- https://mvnrepository.com/artifact/com.github.wvengen/proguard-maven-plugin -->
</dependencies>
<build>
<finalName>sydapi4j</finalName>
@@ -136,7 +107,6 @@
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.2-01</version>
<!-- <version>3.5.0-01</version>-->
<extensions>true</extensions>
</plugin>
@@ -212,22 +182,6 @@
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxx.uploadFile</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
@@ -254,9 +208,12 @@
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.Sample.TestDemo</mainClass>
<mainClass>sample.TestDemo</mainClass>
</manifest>
</archive>
<descriptorRefs>
@@ -45,6 +45,9 @@ public class SydApiException extends RuntimeException{
case 4:
msg = "DER 编码格式错误(公钥) ";
break;
case 0xd:
msg = "公钥加密错误";
break;
case 21:
msg = "输入的数据格式错误 ";
break;
@@ -0,0 +1,42 @@
package com.sunyard.entity;
import java.nio.ByteBuffer;
public class MutiReturn7 {
// 返回码
private int ret;
// 0-不是最后 1-是最后
private int isLast;
// 数据
private ByteBuffer data;
public MutiReturn7(int ret, int isLast, ByteBuffer data) {
this.ret = ret;
this.isLast = isLast;
this.data = data;
}
public int getRet() {
return ret;
}
public void setRet(int ret) {
this.ret = ret;
}
public int getIsLast() {
return isLast;
}
public void setIsLast(int isLast) {
this.isLast = isLast;
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
}
@@ -0,0 +1,44 @@
package com.sunyard.util;
import java.nio.ByteBuffer;
public class ByteBufferUtil {
public static ByteBuffer sliceRange(ByteBuffer source, int start, int length) {
// 保存原 buffer 的 position 和 limit
int oldPos = source.position();
int oldLimit = source.limit();
// 设置新的 position 和 limit 为目标区间
source.position(start);
source.limit(start + length);
// 创建共享视图(零拷贝)
ByteBuffer slice = source.slice();
// 恢复原 buffer 的 position 和 limit
source.position(oldPos);
source.limit(oldLimit);
return slice;
}
public static ByteBuffer sliceAndConsume(ByteBuffer source, int length) {
// 保存原 buffer 的 position 和 limit
int oldPos = source.position();
int oldLimit = source.limit();
// 设置新的 position 和 limit 为目标区间
int start = oldPos;
source.position(start);
source.limit(start + length);
// 创建共享视图(零拷贝)
ByteBuffer slice = source.slice();
// 恢复原 buffer 的 position 和 limit
source.position(oldPos + length);
source.limit(oldLimit);
return slice;
}
}
@@ -0,0 +1,367 @@
package com.sunyard.util;
import java.util.Collection;
import java.util.Map;
/**
* 参数检查工具类,提供常见的参数校验方法。
* <p>
* 所有方法在校验失败时均抛出 {@link IllegalArgumentException} 异常,
* 并附带包含参数名的明确错误信息。成功时返回被校验的值,便于链式调用。
* </p>
*
* <p>使用示例:
* <pre>{@code
* public void setAge(int age) {
* ParamChecker.checkInRange(age, "age", 0, 150);
* }
*
* public void setName(String name) {
* ParamChecker.checkNotBlank(name, "name");
* }
*
* public void setStatus(int status) {
* ParamChecker.checkInValues(status, "status", 1, 2, 3);
* }
* }</pre>
* </p>
*
* @author Cheney
*/
public final class ParamChecker {
private ParamChecker() {
// 私有构造器,防止实例化
}
/**
* 检查表达式是否为真,若为假则抛出异常。
*
* @param expression 待检查的布尔表达式
* @param message 异常信息
* @throws IllegalArgumentException 如果 expression 为 false
*/
public static void checkArgument(boolean expression, String message) {
if (!expression) {
throw new IllegalArgumentException(message);
}
}
// ==================== 对象非空检查 ====================
/**
* 检查对象不为 null。
*
* @param obj 待检查的对象
* @param paramName 参数名称(用于异常信息)
* @param <T> 对象类型
* @return 传入的对象(便于链式调用)
* @throws IllegalArgumentException 如果 obj 为 null
*/
public static <T> T checkNotNull(T obj, String paramName) {
if (obj == null) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null");
}
return obj;
}
// ==================== 字符串检查 ====================
/**
* 检查字符串不为 null 且长度大于 0(不忽略空白字符)。
*
* @param str 待检查的字符串
* @param paramName 参数名称
* @return 传入的字符串
* @throws IllegalArgumentException 如果 str 为 null 或空字符串
*/
public static String checkNotEmpty(String str, String paramName) {
if (str == null || str.isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空字符串");
}
return str;
}
/**
* 检查字符串不为 null 且去除首尾空白后长度大于 0。
*
* @param str 待检查的字符串
* @param paramName 参数名称
* @return 传入的字符串(原值,非 trim 后结果)
* @throws IllegalArgumentException 如果 str 为 null 或仅包含空白字符
*/
public static String checkNotBlank(String str, String paramName) {
if (str == null || !str.trim().isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null、空字符串或仅包含空白字符");
}
return str;
}
/**
* 检查字符串长度在指定范围内(包含边界)。
*
* @param str 待检查的字符串
* @param paramName 参数名称
* @param min 最小长度(包含)
* @param max 最大长度(包含)
* @return 传入的字符串
* @throws IllegalArgumentException 如果 str 为 null,或长度不在 [min, max] 范围内
*/
public static String checkLengthBetween(String str, String paramName, int min, int max) {
checkNotNull(str, paramName);
if (min > max) {
throw new IllegalArgumentException("内部错误:长度检查的最小值 " + min + " 不能大于最大值 " + max);
}
int len = str.length();
if (len < min || len > max) {
throw new IllegalArgumentException(
String.format("参数 '%s' 的长度 %d 不在允许范围 [%d, %d] 内", paramName, len, min, max));
}
return str;
}
// ==================== 整数(int)检查 ====================
/**
* 检查 int 值大于 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value <= 0
*/
public static int checkPositive(int value, String paramName) {
if (value <= 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 必须为正数,当前值: " + value);
}
return value;
}
/**
* 检查 int 值 >= 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value < 0
*/
public static int checkNonNegative(int value, String paramName) {
if (value < 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为负数,当前值: " + value);
}
return value;
}
/**
* 检查 int 值在指定范围内(包含边界)。
*
* @param value 待检查的值
* @param paramName 参数名称
* @param min 最小值(包含)
* @param max 最大值(包含)
* @return 传入的值
* @throws IllegalArgumentException 如果 value 不在 [min, max] 范围内,或 min > max
*/
public static int checkInRange(int value, String paramName, int min, int max) {
if (min > max) {
throw new IllegalArgumentException("内部错误:范围检查的最小值 " + min + " 不能大于最大值 " + max);
}
if (value < min || value > max) {
throw new IllegalArgumentException(
String.format("参数 '%s' 的值 %d 不在允许范围 [%d, %d] 内", paramName, value, min, max));
}
return value;
}
/**
* 检查 int 值是否等于给定集合中的任意一个值。
*
* @param value 待检查的值
* @param paramName 参数名称
* @param validValues 允许的值列表
* @return 传入的值
* @throws IllegalArgumentException 如果 value 不在 validValues 中,或 validValues 为空
*/
public static int checkInValues(int value, String paramName, int... validValues) {
if (validValues == null || validValues.length == 0) {
throw new IllegalArgumentException("内部错误:允许的值集合不能为空");
}
for (int v : validValues) {
if (value == v) {
return value;
}
}
// 构建允许值字符串用于提示
StringBuilder allowed = new StringBuilder();
for (int i = 0; i < validValues.length; i++) {
if (i > 0) allowed.append(", ");
allowed.append(validValues[i]);
}
throw new IllegalArgumentException(
String.format("参数 '%s' 的值 %d 不在允许值集合 [%s] 中", paramName, value, allowed));
}
// ==================== 长整型(long)检查 ====================
/**
* 检查 long 值大于 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value <= 0
*/
public static long checkPositive(long value, String paramName) {
if (value <= 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 必须为正数,当前值: " + value);
}
return value;
}
/**
* 检查 long 值 >= 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value < 0
*/
public static long checkNonNegative(long value, String paramName) {
if (value < 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为负数,当前值: " + value);
}
return value;
}
/**
* 检查 long 值在指定范围内(包含边界)。
*
* @param value 待检查的值
* @param paramName 参数名称
* @param min 最小值(包含)
* @param max 最大值(包含)
* @return 传入的值
* @throws IllegalArgumentException 如果 value 不在 [min, max] 范围内,或 min > max
*/
public static long checkInRange(long value, String paramName, long min, long max) {
if (min > max) {
throw new IllegalArgumentException("内部错误:范围检查的最小值 " + min + " 不能大于最大值 " + max);
}
if (value < min || value > max) {
throw new IllegalArgumentException(
String.format("参数 '%s' 的值 %d 不在允许范围 [%d, %d] 内", paramName, value, min, max));
}
return value;
}
// ==================== 浮点数(double)简单检查 ====================
/**
* 检查 double 值大于 0(考虑极小正数,不做精度处理)。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value <= 0 或为 NaN
*/
public static double checkPositive(double value, String paramName) {
if (value <= 0 || Double.isNaN(value)) {
throw new IllegalArgumentException("参数 '" + paramName + "' 必须为正数,当前值: " + value);
}
return value;
}
/**
* 检查 double 值 >= 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value < 0 或为 NaN
*/
public static double checkNonNegative(double value, String paramName) {
if (value < 0 || Double.isNaN(value)) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为负数或 NaN,当前值: " + value);
}
return value;
}
// ==================== 集合与数组非空检查 ====================
/**
* 检查集合不为 null 且非空。
*
* @param coll 待检查的集合
* @param paramName 参数名称
* @param <T> 集合元素类型
* @return 传入的集合
* @throws IllegalArgumentException 如果 coll 为 null 或空集合
*/
public static <T> Collection<T> checkNotEmpty(Collection<T> coll, String paramName) {
if (coll == null || coll.isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空集合");
}
return coll;
}
/**
* 检查 Map 不为 null 且非空。
*
* @param map 待检查的 Map
* @param paramName 参数名称
* @param <K> 键类型
* @param <V> 值类型
* @return 传入的 Map
* @throws IllegalArgumentException 如果 map 为 null 或空 Map
*/
public static <K, V> Map<K, V> checkNotEmpty(Map<K, V> map, String paramName) {
if (map == null || map.isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空 Map");
}
return map;
}
/**
* 检查数组不为 null 且长度大于 0。
*
* @param array 待检查的数组
* @param paramName 参数名称
* @param <T> 数组元素类型
* @return 传入的数组
* @throws IllegalArgumentException 如果 array 为 null 或长度为 0
*/
public static <T> T[] checkNotEmpty(T[] array, String paramName) {
if (array == null || array.length == 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空数组");
}
return array;
}
// ==================== 布尔条件检查 ====================
/**
* 检查布尔条件为 true。
*
* @param condition 待检查的条件
* @param paramName 参数名称(描述条件含义)
* @throws IllegalArgumentException 如果 condition 为 false
*/
public static void checkTrue(boolean condition, String paramName) {
if (!condition) {
throw new IllegalArgumentException("参数条件 '" + paramName + "' 必须为 true");
}
}
/**
* 检查布尔条件为 false。
*
* @param condition 待检查的条件
* @param paramName 参数名称(描述条件含义)
* @throws IllegalArgumentException 如果 condition 为 true
*/
public static void checkFalse(boolean condition, String paramName) {
if (condition) {
throw new IllegalArgumentException("参数条件 '" + paramName + "' 必须为 false");
}
}
}
+308 -28
View File
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ByteUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sunyard.RetWrap;
@@ -13,6 +14,7 @@ import com.sunyard.SydApiException;
import com.sunyard.cert.X509;
import com.sunyard.constant.CertUsage;
import com.sunyard.entity.ImportResult;
import com.sunyard.entity.MutiReturn7;
import com.sunyard.entity.Struct;
import com.sunyard.log.ILogFactory;
import com.sunyard.log.ILogger;
@@ -49,6 +51,7 @@ import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.security.NoSuchProviderException;
import java.security.Security;
@@ -2584,48 +2587,68 @@ public class SydApi4j implements SydApi {
private ByteBuffer read(Socket socket) throws IOException {
InputStream is = socket.getInputStream();
int d;
int high = is.read();
int low = is.read();
int len = (high << 8) + low;
byte[] buf = new byte[2];
int offset = 0;
int remaining = 2;
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;
if(debug){
print("H\t");
println(Integer.toHexString(high));
print("L\t");
println(Integer.toHexString(low));
print("Len\t");
print("接收数据\t");
// print("H=");
// print(Integer.toHexString(high));
// print("\tL=");
// print(Integer.toHexString(low));
print("\tLen=");
println(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)})));
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)})));
// 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) {
d = is.read();
if (-1 == d) {
break;
while (remaining > 0) {
int toRead = Math.min(remaining, buffer.length);
int bytesRead = is.read(buffer, 0, toRead);
if (bytesRead == -1) {
// 与原逻辑不同:这里抛异常,而不是静默退出
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()) {
// print("EBCD 数据: \t");
@@ -2660,8 +2683,10 @@ public class SydApi4j implements SydApi {
ByteBuffer bb = read(socket);
return bb;
} catch (SocketTimeoutException e) {
throw new SydApiException("接收数据超时", -2);
} catch (EOFException e) {
throw new SydApiException("接收数据不完整", -21, e);
}catch (SocketTimeoutException e) {
throw new SydApiException("接收数据超时", -2, e);
} catch (Exception e) {
e.printStackTrace();
}
@@ -6789,6 +6814,8 @@ public class SydApi4j implements SydApi {
}
@Override
public String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData) {
Proto77 proto = new Proto77();
@@ -6825,6 +6852,259 @@ public class SydApi4j implements SydApi {
return SYMUtil.derEnData2Base64EnC1C2C3(((PacketSection) ret.get("cipherData")).getBytes());
}
public byte[] SYD_SM2Encrypt(byte[] publicKey, byte[] pOrgData){
ParamChecker.checkNotNull(publicKey, "publicKey");
ParamChecker.checkNotNull(pOrgData, "pOrgData");
final int CHUNK_SIZE = 63 * 1024; // 64 KB
int dataLen = pOrgData.length;
int offset = 0;
while (offset < dataLen) {
int len = Math.min(CHUNK_SIZE, dataLen - offset);
// 调用底层支持偏移量的加密方法
SYD_SM2Encrypt(1, publicKey, ByteBuffer.wrap(pOrgData, offset, len), offset);
offset += len;
}
// 计算
SYD_SM2Encrypt(2, publicKey, null, 0);
// 取回
int idx = 0;
List<ByteBuffer> chunks = new ArrayList<>();
int totalLen = 0;
int isLast = 0;
while (isLast != 1) {
MutiReturn7 ret = SYD_SM2Encrypt(3, null, null, idx);
ByteBuffer bb = ret.getData();
isLast = ret.getIsLast();
if (bb != null && bb.remaining() > 0) {
int remaining = bb.remaining();
chunks.add(bb); // 直接存储,不需要 duplicate
totalLen += remaining;
idx += remaining;
} else if (isLast != 1) {
// 没有数据但还不是最后一块,异常
throw new RuntimeException("Empty 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;
}
// @Override
// 支持大包加解密
private MutiReturn7 SYD_SM2Encrypt(int dataType, byte[] publicKey, ByteBuffer pOrgData, int idx) {
// 参数检查
ParamChecker.checkInRange(dataType, "dataType", 1, 3);
// 最大缓存 64K
// 根据输入数据快速估算缓存大小
int buffLen = 4096;
if( 1 == dataType ) {
buffLen = pOrgData.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("7F".getBytes());
bb.put((byte) dataType); // 数据包标志
if ( 2 == dataType ) { // 公钥
bb.put(ByteUtil.shortToBytes((short) publicKey.length, ByteOrder.BIG_ENDIAN) );
bb.put(publicKey);
}
if ( 1 == dataType ) { // 数据
bb.put(ByteUtil.shortToBytes((short) pOrgData.limit(), ByteOrder.BIG_ENDIAN));
bb.put(pOrgData);
bb.put(ByteUtil.intToBytes(idx));
}
if ( 3 == dataType) { // 仅数据长度
bb.put( ByteUtil.shortToBytes((short) (63*1024), ByteOrder.BIG_ENDIAN) );
bb.put( ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
}
// 重新计算长度
int len = bb.position();
len -= 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);
byte[] code = new byte[2];
bb.get(code);
int retCode = Integer.valueOf(new String(code));
if (0 != retCode) {
throw new SydApiException(retCode);
}
// 只有类型是 3 时有数据结果
if ( 3 == dataType ){
int isLast = bb.get();
byte[] dataLenArr = new byte[2];
bb.get(dataLenArr);
int dataLen = ByteUtil.bytesToInt(dataLenArr, ByteOrder.BIG_ENDIAN);
// byte[] data = new byte[dataLen];
// bb.get(data);
ByteBuffer slice = ByteBufferUtil.sliceAndConsume(bb, dataLen);
return new MutiReturn7(retCode, isLast, slice);
} else {
return new MutiReturn7(retCode, 0, null);
}
}
/**
* 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, ByteOrder.BIG_ENDIAN));
bb.put(privateKey);
}
if (dataType == 1) { // 密文块
bb.put(ByteUtil.shortToBytes((short) pCipherData.limit(), ByteOrder.BIG_ENDIAN));
bb.put(pCipherData);
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
}
if (dataType == 3) { // 请求明文块
bb.put(ByteUtil.shortToBytes((short) (63 * 1024), ByteOrder.BIG_ENDIAN));
bb.put(ByteUtil.intToBytes(idx, ByteOrder.BIG_ENDIAN));
}
// 填写总长度(长度字段本身不包含在内)
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, ByteOrder.BIG_ENDIAN);
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();
+107
View File
@@ -0,0 +1,107 @@
package cmbpoc;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.proto.PacketSection;
import com.sunyard.proto.Util;
import org.junit.*;
import racal.sunyard.main.SydApi4j;
public class FunctionTest {
private SydApi4j api;
private String keypairIndex4Sign = "0000000000000sge00000000001";
private String keypairIndex4Ende = "0000000000000sge00100000001";
private byte[] privateKey4Sign;
private byte[] publicKey4Sign;
private byte[] privateKey4Ende;
private byte[] publicKey4Ende;
private byte[] orgData = new byte[15];
private String sign;
@Before
public void start(){
// 调试模式
System.setProperty("com.sunyard.sydapi4j.debug", "true");
// 建立链接(单台)
this.api = (SydApi4j) new SydApi4j().connect("192.168.100.145", 8889, null, 5000);
// RetWrap keypair = this.getPrivateKeyAndPublickKey(keypairIndex4Sign);
// this.publicKey4Sign = Util.hexString2Bytes( keypair.get("pk").toString() );
// this.privateKey4Sign = Util.hexString2Bytes( keypair.get("sk").toString() );
//
// RetWrap keypair4Ende = this.getPrivateKeyAndPublickKey(keypairIndex4Sign);
// this.publicKey4Ende = Util.hexString2Bytes( keypair4Ende.get("pk").toString() );
// this.privateKey4Ende = Util.hexString2Bytes( keypair4Ende.get("sk").toString() );
this.publicKey4Ende = Util.hexString2Bytes("03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7");
this.privateKey4Ende = Util.hexString2Bytes("00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000");
}
@After
public void stop(){
if ( null != api ) {
this.api.disconnect();
this.api = null;
}
}
@Ignore
@Test
public void genKeyPair(){
// RetWrap r = this.api.SYD_SM2GenKeyPair();
// String pk = r.get("publicKey").toString();
// String sk = r.get("privateKey").toString();
//
// System.out.println("pk=" + pk);
// System.out.println("sk=" + sk);
//
// this.privateKey4Sign = Util.hexString2Bytes(sk);
// this.publicKey4Sign = Util.hexString2Bytes(pk);
RetWrap rw = this.api.SM2GenKeyPair();
byte[] pk = (byte[]) rw.get(SydApi.RET_PUBLIC_KEY);
byte[] sk = (byte[]) rw.get(SydApi.RET_PRIVATE_KEY);
System.out.println("pk=" + Util.bytes2HexString(pk));
System.out.println("sk=" + Util.bytes2HexString(sk));
}
public RetWrap getPrivateKeyAndPublickKey(String keypairIndex){
String pk = this.api.SM2GetPublicKeyC(keypairIndex);
String sk = this.api.SM2GetPrivateKeyC(keypairIndex);
System.out.println("pk=" + pk);
System.out.println("sk=" + sk);
RetWrap retWrap = new RetWrap();
retWrap.put("pk", pk);
retWrap.put("sk", sk);
return retWrap;
}
@Test
public void SYD_SM2_Sign(){
String sign = this.api.SYD_SM2_Sign_HA(1, privateKey4Sign, publicKey4Sign, orgData);
this.api.SYD_SM2_Verify_HA(1, publicKey4Sign, orgData, sign);
}
@Test
public void SYD_SM2_Encrypt(){
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData);
// byte[] deData = this.api.SYD_SM2Decrypt(publicKey4Ende, enData);
// Assert.assertArrayEquals(enData, deData);
}
}
+76
View File
@@ -0,0 +1,76 @@
package cmbpoc;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
public class JmeterTest extends AbstractJavaSamplerClient {
private byte[] publicKey;
private byte[] plainData;
private int sleep = 1;
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("function", "sleep");
params.addArgument("sleep", "1");
return params;
}
@Override
public void setupTest(JavaSamplerContext context) {
// 校准测试
sleep = context.getIntParameter("sleep", 1);
// 线程开始时准备解密、验签数据
String function = context.getParameter("function");
switch (function) {
case "SYD_SM2_Sign":
break;
default:
break;
}
}
@Override
public SampleResult runTest(JavaSamplerContext context) {
SampleResult result = new SampleResult();
// 调用待测函数
String function = context.getParameter("function");
result.sampleStart(); // 开始计时
try {
switch (function) {
case "SYD_SM2_Sign":
break;
case "sleep":
Thread.sleep( this.sleep );
break;
default:
break;
}
// result.setResponseData(encrypted); // 可选
result.setSuccessful(true);
result.setResponseCodeOK();
result.setResponseMessage( function + "执行成功" );
} catch (Exception e) {
result.setSuccessful(false);
result.setResponseCode("500");
result.setResponseMessage( function + "执行失败。" + e.getMessage());
} finally {
result.sampleEnd(); // 结束计时
}
return result;
}
@Override
public void teardownTest(JavaSamplerContext context) {
// 释放资源(如有)
}
}
@@ -0,0 +1,84 @@
package cmbpoc;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.proto.Util;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
public class SignatureVerifyTest {
private SydApi4j api;
private byte[] orgData;
private String SM2dn;
@Before
public void setUp() {
System.setProperty("com.sunyard.sydapi4j.debug", "true");
this.api = (SydApi4j) new SydApi4j().connect("172.1.41.139", 8889, null, 3000);
this.orgData = "Hello, World! 测试数据".getBytes();
this.SM2dn = "C=cn,O=CFCA OCA1 SM2,OU=Local RA OCA1,OU=Units,CN=041@N91330108762038374D@sunyard@00000064";
}
@After
public void tearDown() {
if (api != null) {
this.api.disconnect();
this.api = null;
}
}
@Test
public void testP1SignAndVerify() {
byte[] sign = this.api.SYD_NakedSign(orgData, SM2dn);
Assert.assertNotNull("P1签名结果不应为空", sign);
System.out.println("P1签名结果: " + Util.bytes2HexString(sign));
boolean verifyResult = this.api.SYD_NakedVerify(orgData, sign, SM2dn);
Assert.assertTrue("P1验签应通过", verifyResult);
System.out.println("P1验签结果: " + verifyResult);
}
@Test
public void testP7DetachSignAndVerify() {
String sign = this.api.detachedSign(1, orgData, SM2dn);
Assert.assertNotNull("P7 Detach签名结果不应为空", sign);
System.out.println("P7 Detach签名结果: " + sign);
boolean verifyResult = this.api.detachedVerify(1, orgData, sign);
Assert.assertTrue("P7 Detach验签应通过", verifyResult);
System.out.println("P7 Detach验签结果: " + verifyResult);
}
@Test
public void testP7AttachSignAndVerify() throws Exception {
String sign = this.api.attachedSign(orgData, SM2dn);
Assert.assertNotNull("P7 Attach签名结果不应为空", sign);
System.out.println("P7 Attach签名结果: " + sign);
boolean verifyResult = this.api.attachedVerify(sign);
Assert.assertTrue("P7 Attach验签应通过", verifyResult);
System.out.println("P7 Attach验签结果: " + verifyResult);
}
@Test
public void testDigitalEnvelopeEncryptAndDecrypt() {
RetWrap genResult = this.api.generateDEByDn(SM2dn, orgData);
Assert.assertNotNull("数字信封生成结果不应为空", genResult);
byte[] cipherKey = (byte[]) genResult.get(SydApi.RET_CIPHER_KEY);
Assert.assertNotNull("数字信封密文密钥不应为空", cipherKey);
System.out.println("数字信封密文: " + new String(cipherKey));
RetWrap decryptResult = this.api.decryptDEByDN(SM2dn, cipherKey);
Assert.assertNotNull("数字信封解密结果不应为空", decryptResult);
byte[] decryptedData = (byte[]) decryptResult.get("oData");
Assert.assertNotNull("解密数据不应为空", decryptedData);
Assert.assertArrayEquals("解密数据应与原始数据一致", orgData, decryptedData);
System.out.println("数字信封解密结果: " + new String(decryptedData));
}
}
@@ -1,50 +0,0 @@
package com.sunyard.sydapi.loadrunner;
import com.sunyard.sydapi.loadrunner.action1.Actions;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
public class ShangTest {
private static final String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
private static final byte[] testData = new byte[ 4 * 1024 ];
private SydApi4j api = null;
public void init() throws Exception {
if ( null == api ) {
api = (SydApi4j) new SydApiBuilder()
.setIp("172.16.18.59") // 192.168.0.162
.setPort( 8889 )
.useDebugMode()
.build();
}
}
public void action(){
String sign = api.attachedSign(testData, dn);
boolean ret = api.attachedVerify( sign );
assert ret;
}
public void end(){
if (null != this.api ) {
this.api.disconnect();
}
}
public static void main(String[] args) throws Throwable {
System.out.println( SydApi4j.getVersion() );
// Actions test = new Actions();
ShangTest test = new ShangTest();
test.init();
test.action();
test.end();
}
}
@@ -1,44 +0,0 @@
package com.sunyard.sydapi.loadrunner.action1;
/*
* LoadRunner Java script. (Build: _build_number_)
*
* Script Description:
*
*/
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
public class Actions
{
private static final byte[] testData = new byte[ 4 * 1024 ];
private SydApi4j api = null;
public int init() throws Throwable {
if ( null == api ) {
api = (SydApi4j) new SydApiBuilder()
.setIp("172.16.18.59")
.setPort( 8889 )
.useDebugMode()
.build();
}
return 0;
}//end of init
public int action() throws Throwable {
api.SM3Hash( testData );
return 0;
}//end of action
public int end() throws Throwable {
if (null != this.api ) {
this.api.disconnect();
}
return 0;
}//end of end
}
@@ -1,75 +0,0 @@
package com.sunyard.sydapi.loadrunner.raw;
/*
* LoadRunner Java script. (Build: _build_number_)
*
* Script Description:
*
*/
import lrapi.lr;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
import com.sunyard.proto.Util;
import com.sunyard.SydApi;
public class Actions
{
private static final String inHexData = "67c6697351ff4aec29cdbaabf2fbe346";
private static String pk ;
private static String sk ;
private SydApi api;
public int init() throws Throwable {
SydApiBuilder builder = new SydApiBuilder().setIp("192.168.1.123");
api = builder.build();
this.pk = api.SM2GetPublicKeyC("123", 0 );
this.sk = api.SM2GetPrivateKeyC("123");
return 0;
}//end of init
public int action() throws Throwable {
lr.start_transaction("auto");//设置事务开始点
try {
System.out.println("begin SYD_Sign_P1");
byte[] sign = this.api.SM2SignC( 0 , sk, Util.hexString2Bytes(pk), Util.hexString2Bytes(inHexData) );
System.out.println("sign=" + Util.bytes2HexString( sign ));
System.out.println("begin SYD_Verify_P1");
boolean pass = api.SM2Verify(1, Util.hexString2Bytes(pk), Util.hexString2Bytes(inHexData), sign );
System.out.println("验签结果 " + pass);
System.out.println("end SYD_Verify_P1");
} finally {
lr.end_transaction("auto", lr.AUTO);//设置事务结束点
}
return 0;
}//end of action
public int end() throws Throwable {
return 0;
}//end of end
public static void main(String[] args) throws Throwable {
Actions actions = new Actions();
actions.init();
actions.action();
actions.end();
}
}
@@ -1,76 +0,0 @@
package com.sunyard.sydapi.loadrunner.raw_uid;
/*
* LoadRunner Java script. (Build: _build_number_)
*
* Script Description:
*
*/
import lrapi.lr;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
import com.sunyard.proto.Util;
import com.sunyard.SydApi;
public class Actions
{
private static final String inHexData = "67c6697351ff4aec29cdbaabf2fbe346";
private static final String uid = "8765432187654321";
private static String pk ;
private static String sk ;
private SydApi api;
public int init() throws Throwable {
SydApiBuilder builder = new SydApiBuilder().setIp("192.168.1.123");
api = builder.build();
this.pk = api.SM2GetPublicKeyC("123", 0 );
this.sk = api.SM2GetPrivateKeyC("123");
return 0;
}//end of init
public int action() throws Throwable {
lr.start_transaction("auto");//设置事务开始点
try {
System.out.println("begin SYD_Sign_P1");
byte[] sign = this.api.SM2SignC( 0, uid , sk, Util.hexString2Bytes(pk), Util.hexString2Bytes(inHexData) );
System.out.println("sign=" + Util.bytes2HexString( sign ));
System.out.println("begin SYD_Verify_P1");
boolean pass = api.SM2Verify( uid, 1, Util.hexString2Bytes(pk), Util.hexString2Bytes(inHexData), sign );
System.out.println("验签结果 " + pass);
System.out.println("end SYD_Verify_P1");
} finally {
lr.end_transaction("auto", lr.AUTO);//设置事务结束点
}
return 0;
}//end of action
public int end() throws Throwable {
return 0;
}//end of end
public static void main(String[] args) throws Throwable {
Actions actions = new Actions();
actions.init();
actions.action();
actions.end();
}
}
@@ -22,7 +22,7 @@ public class CertTest {
public static void main(String[] args) {
//System.setProperty("com.sunyard.sydapi4j.debug", "true");
SydApi4j api = (SydApi4j) new SydApi4j().connect("172.16.18.5", 8889, null, 1000);
SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.1.129", 8889, null, 1000);
try{
List<String>dns = api.getAllCert();
System.out.println(Arrays.toString( dns.toArray() ) );
@@ -8,54 +8,55 @@ import racal.sunyard.main.SydApiBuilder;
public class TestShangqingXingye {
private static final byte[] orgDataBig = new byte[ 5 * 1024];
private static final byte[] orgData2k = new byte[ 2 * 1024];
private static final String pcDnEN = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
private static final String pcDnEN = "C=CN,O=CFCA TEST SM2 OCA31,OU=SGE,OU=Organizational-2,CN=SGE051@7028-702821-b70280002@Z000000001@1";
private static final String pcDnEN2 = "C=CN,O=OCA31SM2,OU=Local RA OCA31,OU=Organizational-2,CN=CFCA@sunyard@N91330108762038374D@52";
public static void main(String[] args) {
//System.setProperty("com.sunyard.sydapi4j.debug", "true");
long startTime = System.currentTimeMillis(); //获取开始时间
SydApiBuilder builder = new SydApiBuilder().setIp("192.168.0.100");
SydApiBuilder builder = new SydApiBuilder().setIp("172.1.41.214");
SydApi4j api = (SydApi4j) builder.build();
try {
/**
* 产生对称密钥,通过公钥加密生成数字信封,。
* @param pcDnEN: 清算所的公钥证书
* @param pcData: 明文数据。
* @return RetWrap: 数字信封
*/
RetWrap signData = api.generateDEByDn(pcDnEN, orgDataBig);
byte[] cpkey2 = (byte[]) signData.get("CipherKey");
System.out.println("加密信封:" + new String(cpkey2));
/**
* 接收用私钥解密数字信封,还原原文。。
* @param pcDnEN: 清算所的公钥证书
* @param cpkey: 数字信封。
* @return preData: 原数据
*/
RetWrap oDataWrap = api.decryptDEByDN(pcDnEN, cpkey2);
byte[] preData = (byte[]) oDataWrap.get("oData");
System.out.println("解密信封:" + Util.bytes2HexString(preData));
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7),
* @param orgData: 待签名的原始数据
* @param pcDnEN: 签名者证书 DN
* @return signsData: 签名数据
*/
String signsData = api.SYD_SM2_DetachedSign_HA(orgData2k, pcDnEN);
System.out.println("签名数据:" + signsData);
/**
* 利用清算所的公钥证书对签名数据进行验签。
* @param dataType: 数据模式, 0:输入的数据为 HASH 后的数据, 1:输入的数据为原始数据库(本次传入1)
* @param orgData: 待签名的原始数据
* @param sign: 签名数据。
*/
boolean result = api.detachedVerify(1, orgData2k, signsData);
System.out.println("验签结果:" + result);
// /**
// * 产生对称密钥,通过公钥加密生成数字信封,。
// * @param pcDnEN: 清算所的公钥证书
// * @param pcData: 明文数据。
// * @return RetWrap: 数字信封
// */
// RetWrap signData = api.generateDEByDn(pcDnEN, orgDataBig);
// byte[] cpkey2 = (byte[]) signData.get("CipherKey");
// System.out.println("加密信封:" + new String(cpkey2));
//
// /**
// * 接收用私钥解密数字信封,还原原文。。
// * @param pcDnEN: 清算所的公钥证书
// * @param cpkey: 数字信封。
// * @return preData: 原数据
// */
// RetWrap oDataWrap = api.decryptDEByDN(pcDnEN, cpkey2);
// byte[] preData = (byte[]) oDataWrap.get("oData");
// System.out.println("解密信封:" + Util.bytes2HexString(preData));
//
//
// /**
// * 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7),
// * @param orgData: 待签名的原始数据
// * @param pcDnEN: 签名者证书 DN
// * @return signsData: 签名数据
// */
// String signsData = api.SYD_SM2_DetachedSign_HA(orgData2k, pcDnEN);
// System.out.println("签名数据:" + signsData);
//
// /**
// * 利用清算所的公钥证书对签名数据进行验签。
// * @param dataType: 数据模式, 0:输入的数据为 HASH 后的数据, 1:输入的数据为原始数据库(本次传入1)
// * @param orgData: 待签名的原始数据
// * @param sign: 签名数据。
// */
// boolean result = api.detachedVerify(1, orgData2k, signsData);
// System.out.println("验签结果:" + result);
/**
@@ -67,7 +68,7 @@ public class TestShangqingXingye {
* @param pcData: 明文数据。
* @return pcSignData: 签名数字信封
*/
String pcSignData = api.SYD_SignDigitalEnvelope(pcDnEN, pcDnEN, orgData2k);
String pcSignData = api.SYD_SignDigitalEnvelope(pcDnEN2, pcDnEN2, orgData2k);
System.out.println("签名数字信封:" + pcSignData);
/**
@@ -79,7 +80,7 @@ public class TestShangqingXingye {
* @return pcData:原数据
*/
byte[] oData = api.SYD_VerifyDigitalEnveloe(pcDnEN, pcDnEN, pcSignData);
byte[] oData = api.SYD_VerifyDigitalEnveloe(pcDnEN2, pcDnEN2, pcSignData);
System.out.println("原数据:" + Util.bytes2HexString(oData));
@@ -1,6 +1,6 @@
package com.jmeter.test;
package jmeter;
import com.Sample.SydUtils;
import sample.SydUtils;
import com.google.gson.Gson;
import com.sunyard.SydApiException;
import com.sunyard.entity.ImportResult;
@@ -17,7 +17,7 @@ import java.nio.charset.StandardCharsets;
import java.util.*;
public class Test4Jemter extends AbstractJavaSamplerClient {
public class Test4Jmeter extends AbstractJavaSamplerClient {
private String SM2dn ;
private String RSAdn ;
-14
View File
@@ -1,14 +0,0 @@
package lrapi;
public class lr {
public static String AUTO = "AUTO";
public static void start_transaction(String t) {
System.out.println("start_transaction" + t);
}
public static void end_transaction(String t, String type) {
System.out.println("end_transaction" + t);
}
}
@@ -1,4 +1,4 @@
package com.Sample;
package sample;
import racal.sunyard.main.SydApi4j;
@@ -1,4 +1,4 @@
package com.sample;
package sample;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONObject;
-3
View File
@@ -1,10 +1,7 @@
package sample;
import cn.hutool.core.date.StopWatch;
import com.Sample.SydUtils;
import com.google.gson.Gson;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.SydApiException;
import com.sunyard.entity.ImportResult;
import com.sunyard.proto.Util;
@@ -1,4 +1,4 @@
package com.Sample;
package sample;
import com.sunyard.RetWrap;
import com.sunyard.proto.Util;