Author SHA1 Message Date
cheney e8a62c1d4a 一个 xml 测试 2026-05-18 17:15:00 +08:00
waner 8de764c731 fix:key漏洞 2025-07-31 11:57:12 +08:00
waner 1df1e64783 fix:key漏洞 2025-07-31 11:57:05 +08:00
waner 6df9d978d5 jmeter测试类 2025-07-25 09:39:03 +08:00
waner 7e4bc7f87b 增加参数范围校验 2025-07-24 18:02:14 +08:00
waner 1f2709326f jmeter测试修改 2025-07-18 09:44:54 +08:00
waner d80e225158 jmeter测试 2025-07-16 15:43:32 +08:00
waner 4372362086 证书导入结果修改 2025-06-19 11:05:12 +08:00
waner b4d3c1d193 jmeter测试完善 2025-06-09 10:51:51 +08:00
waner 9fbcd1baad 单元测试 2025-06-05 09:30:32 +08:00
11 changed files with 920 additions and 265 deletions
+6
View File
@@ -0,0 +1,6 @@
{
"ip1": "172.1.41.3",
"ip2": "172.1.41.139",
"port": 8889,
"dn": "C=cn,O=CFCA OCA1 SM2,OU=Local RA OCA1,OU=Units,CN=041@N91330108762038374D@杭州信雅达科技有限公司@00000002"
}
+2 -2
View File
@@ -108,8 +108,8 @@
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>org.codehaus.groovy</groupId>--> <!-- <groupId>org.codehaus.groovy</groupId>-->
<!-- <artifactId>groovy-all</artifactId>--> <!-- <artifactId>groovy-all</artifactId>-->
<!-- <version>3.0.9</version>--> <!-- <version>2.4.15</version>-->
<!-- <version>4.0.26</version>--> <!--&lt;!&ndash; <version>4.0.26</version>&ndash;&gt;-->
<!-- </dependency>--> <!-- </dependency>-->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>ch.qos.logback</groupId>--> <!-- <groupId>ch.qos.logback</groupId>-->
+38
View File
@@ -0,0 +1,38 @@
package com.Sample;
import racal.sunyard.main.SydApi4j;
public class SydUtils {
private final SydApi4j sydApi4j;
static {
System.setProperty("com.sunyard.dnsort", "true");
}
public SydUtils(String ip1, String ip2, int port, int timeout) {
SydApi4j.SYD_Set_Parameter_HA(ip1, ip2, port, timeout);
sydApi4j = (SydApi4j) new SydApi4j();
}
public void disconnect() {
sydApi4j.disconnect();
}
public byte[] SYD_NakedSign(byte[] orgData, String SM2dn) {
return sydApi4j.SYD_NakedSign(orgData,SM2dn);
}
public boolean SYD_NakedVerify(byte[] orgData, byte[] nakedSign, String SM2dn){
return sydApi4j.SYD_NakedVerify(orgData, nakedSign, SM2dn);
}
public boolean detachedVerify(byte[] orgData, String sign) {
return sydApi4j.detachedVerify(orgData, sign);
}
public String detachedSign(byte[] orgData, String sCertDN) {
return sydApi4j.detachedSign(orgData, sCertDN);
}
}
+165 -90
View File
@@ -1,20 +1,20 @@
package com.jmeter.test; package com.jmeter.test;
import com.Sample.SydUtils;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.sunyard.SydApiException; import com.sunyard.SydApiException;
import com.sunyard.entity.ImportResult;
import com.sunyard.proto.Util; import com.sunyard.proto.Util;
import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.config.Arguments; import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient; import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter.samplers.SampleResult;
import racal.sunyard.main.SydApi4j; import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test4Jemter extends AbstractJavaSamplerClient { public class Test4Jemter extends AbstractJavaSamplerClient {
@@ -37,6 +37,17 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
private int dataLength; private int dataLength;
private String cert;
private String nodes;
private String snmpIP;
private String snmpPort;
private String snmpOID;
private String snmpCommunity;
private int timeout;
private int logSwitch;
/** /**
* 定义默认的参数,在jmeter中会自动显示在这里定义的默认参数 * 定义默认的参数,在jmeter中会自动显示在这里定义的默认参数
@@ -47,15 +58,24 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
Arguments arguments = new Arguments(); Arguments arguments = new Arguments();
arguments.addArgument("SM2dn", "C=CN,ST=zz,L=zz,O=zzz,CN=zzzzz"); arguments.addArgument("SM2dn", "C=CN,ST=zz,L=zz,O=zzz,CN=zzzzz");
arguments.addArgument("RSAdn", "C=cn,O=CFCA TEST CA,OU=NCS2,OU=Enterprises,CN=041@Z402451000010@ShanDong@00000001"); arguments.addArgument("RSAdn", "C=cn,O=CFCA TEST CA,OU=NCS2,OU=Enterprises,CN=041@Z402451000010@ShanDong@00000001");
arguments.addArgument("orgData", "12345678"); arguments.addArgument("orgData", "null");
arguments.addArgument("ip", "172.1.41.139"); arguments.addArgument("ip", "172.1.41.139");
arguments.addArgument("ip2", "172.1.41.96"); arguments.addArgument("ip2", "172.1.41.96");
// arguments.addArgument("port", "8891"); arguments.addArgument("port", "8889");
// arguments.addArgument("ip2", "172.16.17.161"); arguments.addArgument("timeout", "3000");
arguments.addArgument("logSwitch", "1");
// arguments.addArgument("ip2", "172.16.17.161");
arguments.addArgument("dataLength", "1024"); arguments.addArgument("dataLength", "1024");
arguments.addArgument("type", "1"); arguments.addArgument("type", "1");
arguments.addArgument("sign", "12345678"); arguments.addArgument("sign", "12345678");
arguments.addArgument("detachedSign", "12345678"); arguments.addArgument("detachedSign", "12345678");
arguments.addArgument("cert", "");
arguments.addArgument("nodes", "172.1.41.139:8889;172.1.41.96:8889");
arguments.addArgument("snmpIP", "172.1.41.139");
arguments.addArgument("snmpPort", "162");
arguments.addArgument("snmpOID", "1.3.6.1.4.1.9999");
arguments.addArgument("snmpCommunity", "public");
return arguments; return arguments;
} }
@@ -71,12 +91,21 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
oData = context.getParameter("orgData"); oData = context.getParameter("orgData");
ip = context.getParameter("ip"); ip = context.getParameter("ip");
ip2 = context.getParameter("ip2"); ip2 = context.getParameter("ip2");
// port = Integer.parseInt(context.getParameter("8891")); port = context.getIntParameter("port");
// ip2 = context.getParameter("ip2"); timeout = context.getIntParameter("timeout");
logSwitch = context.getIntParameter("logSwitch");
// ip2 = context.getParameter("ip2");
dataLength = context.getIntParameter("dataLength"); dataLength = context.getIntParameter("dataLength");
type = context.getIntParameter("type"); type = context.getIntParameter("type");
sign = context.getParameter("sign"); sign = context.getParameter("sign");
detachedSign = context.getParameter("detachedSign"); detachedSign = context.getParameter("detachedSign");
cert = context.getParameter("cert");
nodes = context.getParameter("nodes");
snmpIP = context.getParameter("snmpIP");
snmpPort = context.getParameter("snmpPort");
snmpOID = context.getParameter("snmpOID");
snmpCommunity = context.getParameter("snmpCommunity");
System.getProperty("com.sunyard.sydapi4j.debug", "false");
System.setProperty("com.sunyard.dnsort", "false"); System.setProperty("com.sunyard.dnsort", "false");
api = new ThreadLocal<SydApi4j>() { api = new ThreadLocal<SydApi4j>() {
@Override @Override
@@ -84,7 +113,7 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
// //
// SydApiBuilder builder = new SydApiBuilder().setIp(ip); // SydApiBuilder builder = new SydApiBuilder().setIp(ip);
// final SydApi4j api = (SydApi4j) builder.build(); // final SydApi4j api = (SydApi4j) builder.build();
SydApi4j.SYD_Set_Parameter_HA(ip, ip2, 8889, 1000); SydApi4j.SYD_Set_Parameter_HA(ip, ip2, port, timeout);
final SydApi4j api1 = (SydApi4j) new SydApi4j(); final SydApi4j api1 = (SydApi4j) new SydApi4j();
return api1; return api1;
} }
@@ -104,133 +133,172 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
sr.setSampleLabel("testDemo"); sr.setSampleLabel("testDemo");
//设置开始标志,否则无法统计tps等 //设置开始标志,否则无法统计tps等
sr.sampleStart(); sr.sampleStart();
SydUtils sydUtils = null;
try { try {
// orgData = oData.getBytes(); //SM2裸签 if ("null".equals(oData)) {
orgData = new byte[dataLength]; orgData = null;
} else {
orgData = oData.getBytes(); //SM2裸签
}
sydUtils = new SydUtils(ip, ip2, port, timeout);
// orgData = new byte[dataLength];
//执行业务逻辑 //执行业务逻辑
switch(type){ switch(type){
case 1: case 1:
// api.get().SYD_NakedSign(SM2dn, orgData, (byte[]) null); // api.get().SYD_NakedSign(SM2dn, orgData, (byte[]) null);
api.get().SYD_NakedSign(orgData,SM2dn); // byte[] nakedSign = api.get().SYD_NakedSign(orgData,SM2dn);
byte[] nakedSign = sydUtils.SYD_NakedSign(orgData,SM2dn);
if (logSwitch == 1) {
System.out.println("p1签名(hex):"+ Util.bytes2HexString(nakedSign));
}
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(Util.encodeBase64(nakedSign1), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(Util.encodeBase64(nakedSign1), StandardCharsets.UTF_8.displayName());
break; break;
case 2: case 2:
// api.get().SYD_NakedVerify(SM2dn, Util.decodeBase64(sign), orgData, (byte[])null) ; // api.get().SYD_NakedVerify(SM2dn, Util.decodeBase64(sign), orgData, (byte[])null) ;
api.get().SYD_NakedVerify(orgData,Util.hexString2Bytes(sign), SM2dn); // boolean flag = api.get().SYD_NakedVerify(orgData,Util.hexString2Bytes(sign), SM2dn);
boolean flag = sydUtils.SYD_NakedVerify(orgData,Util.hexString2Bytes(sign), SM2dn);
if (logSwitch == 1) {
System.out.println("p1验签:"+ flag);
}
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(String.valueOf(nakedVerify1), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(String.valueOf(nakedVerify1), StandardCharsets.UTF_8.displayName());
break; break;
case 3: case 3:
//RSA裸签 //RSA裸签
api.get().SYD_NakedSign(1, RSAdn,orgData,(byte[])null); api.get().SYD_NakedSign(1, RSAdn,orgData,(byte[])null);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(Util.encodeBase64(nakedSign2), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(Util.encodeBase64(nakedSign2), StandardCharsets.UTF_8.displayName());
break; break;
case 4: case 4:
api.get().SYD_NakedVerify(1, RSAdn,Util.decodeBase64(sign),orgData ,(byte[])null); api.get().SYD_NakedVerify(1, RSAdn,Util.decodeBase64(sign),orgData ,(byte[])null);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(String.valueOf(nakedVerify2), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(String.valueOf(nakedVerify2), StandardCharsets.UTF_8.displayName());
break; break;
case 5: case 5:
// api.get().detachedSign(1, orgData, SM2dn); // api.get().detachedSign(1, orgData, SM2dn);
api.get().detachedSign(orgData, SM2dn); //p7 detached签名
String detachedSign1 = sydUtils.detachedSign(orgData, SM2dn);
if (logSwitch == 1) {
System.out.println("p7 detach签名:"+ detachedSign1);
}
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(detSign1, StandardCharsets.UTF_8.displayName()); //sr.setResponseData(detSign1, StandardCharsets.UTF_8.displayName());
break; break;
case 6: case 6:
// api.get().detachedVerify(1, orgData, sign); // api.get().detachedVerify(1, orgData, sign);
api.get().detachedVerify(orgData, detachedSign); //p7 detached验签
// boolean ver = api.get().detachedVerify(orgData, detachedSign);
boolean ver = sydUtils.detachedVerify(orgData, detachedSign);
if (logSwitch == 1) {
System.out.println("p7 detach验签:"+ ver);
}
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(String.valueOf(detV1), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(String.valueOf(detV1), StandardCharsets.UTF_8.displayName());
break; break;
case 7: case 7:
api.get().detachedSign(2,1, orgData, RSAdn); api.get().detachedSign(2,1, orgData, RSAdn);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(detSign2, StandardCharsets.UTF_8.displayName()); //sr.setResponseData(detSign2, StandardCharsets.UTF_8.displayName());
break; break;
case 8: case 8:
api.get().detachedVerify(2,2, orgData, sign); api.get().detachedVerify(2,2, orgData, sign);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(String.valueOf(detV2), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(String.valueOf(detV2), StandardCharsets.UTF_8.displayName());
break; break;
case 9: case 9:
api.get().attachedSignHsm(orgData, SM2dn); api.get().attachedSignHsm(orgData, SM2dn);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(attSign1, StandardCharsets.UTF_8.displayName()); //sr.setResponseData(attSign1, StandardCharsets.UTF_8.displayName());
break; break;
case 10: case 10:
api.get().attachedVerify( sign.getBytes()); api.get().attachedVerify( sign.getBytes());
sr.setResponseCodeOK(); sr.setResponseCodeOK();
// sr.setResponseData(String.valueOf(attV1), StandardCharsets.UTF_8.displayName()); // sr.setResponseData(String.valueOf(attV1), StandardCharsets.UTF_8.displayName());
break; break;
case 11: case 11:
api.get().attachedSignRSAHsm(2, orgData, RSAdn); api.get().attachedSignRSAHsm(2, orgData, RSAdn);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
// sr.setResponseData(attSign2, StandardCharsets.UTF_8.displayName()); // sr.setResponseData(attSign2, StandardCharsets.UTF_8.displayName());
break; break;
case 12: case 12:
api.get().attachedVerifyRSA(2, sign); api.get().attachedVerifyRSA(2, sign);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
// sr.setResponseData(String.valueOf(attV2), StandardCharsets.UTF_8.displayName()); // sr.setResponseData(String.valueOf(attV2), StandardCharsets.UTF_8.displayName());
break; break;
case 13: case 13:
api.get().generateDE(SM2dn.getBytes(), 3, 1, orgData); api.get().generateDE(SM2dn.getBytes(), 3, 1, orgData);
// byte[] cipherKey = (byte[]) genSM2.get(SydApi.RET_CIPHER_KEY); // byte[] cipherKey = (byte[]) genSM2.get(SydApi.RET_CIPHER_KEY);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
// sr.setResponseData(new String(cipherKey), StandardCharsets.UTF_8.displayName()); // sr.setResponseData(new String(cipherKey), StandardCharsets.UTF_8.displayName());
break; break;
case 14: case 14:
api.get().decryptDE(true, 1, SM2dn.getBytes(), sign);; api.get().decryptDE(true, 1, SM2dn.getBytes(), sign);;
// byte[] oData = (byte[]) denSM2.get("oData"); // byte[] oData = (byte[]) denSM2.get("oData");
sr.setResponseCodeOK(); sr.setResponseCodeOK();
// sr.setResponseData(new String(oData), StandardCharsets.UTF_8.displayName()); // sr.setResponseData(new String(oData), StandardCharsets.UTF_8.displayName());
break; break;
case 15: case 15:
api.get(). generateDE(RSAdn.getBytes(), 4, 1, orgData); api.get().generateDE(RSAdn.getBytes(), 4, 1, orgData);
// byte[] cipherKeyRSA = (byte[]) genRSA.get(SydApi.RET_CIPHER_KEY); // byte[] cipherKeyRSA = (byte[]) genRSA.get(SydApi.RET_CIPHER_KEY);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(new String(cipherKeyRSA), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(new String(cipherKeyRSA), StandardCharsets.UTF_8.displayName());
break; break;
case 16: case 16:
api.get().decryptDERSA(true, 1, RSAdn.getBytes(), sign); api.get().decryptDERSA(true, 1, RSAdn.getBytes(), sign);
// byte[] oDataRSA = (byte[]) denRSA.get("oData"); // byte[] oDataRSA = (byte[]) denRSA.get("oData");
sr.setResponseCodeOK(); sr.setResponseCodeOK();
//sr.setResponseData(new String(oDataRSA), StandardCharsets.UTF_8.displayName()); //sr.setResponseData(new String(oDataRSA), StandardCharsets.UTF_8.displayName());
break; break;
case 17: case 17:
String cert1 = api.get().getCertBySign(detachedSign);
System.out.println("根据p7签名值获取的证书为:" + cert1);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
break; break;
case 18: case 18:
testAhnx(); testAhnx(sydUtils);
sr.setResponseCodeOK(); sr.setResponseCodeOK();
break; break;
case 19: case 19:
testImportCert(); testImportCert();
sr.setResponseCodeOK(); sr.setResponseCodeOK();
break; break;
case 20:
boolean delFlag = api.get().deleteCert(SM2dn);
System.out.println("删除证书成功:"+ delFlag);
break;
case 21:
SydApi4j.SYD_Set_Parameter_HA(ip, ip2, port, timeout);
break;
case 22:
api.get().connect(ip, port, "", timeout);
break;
case 23:
api.get().disconnect();
break;
default: default:
sr.setResponseCodeOK(); sr.setResponseCodeOK();
sr.setResponseData("请选择测试组", StandardCharsets.UTF_8.displayName()); sr.setResponseData("请选择测试组", StandardCharsets.UTF_8.displayName());
break; break;
} }
sr.setSuccessful(true); sr.setSuccessful(true);
}catch (SydApiException e){ }catch (SydApiException e){
@@ -239,57 +307,60 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
sr.setResponseData(e.getMessage(), StandardCharsets.UTF_8.displayName()); sr.setResponseData(e.getMessage(), StandardCharsets.UTF_8.displayName());
sr.setSuccessful(false); sr.setSuccessful(false);
}finally { }finally {
if (sydUtils != null) {
sydUtils.disconnect();
}
sr.sampleEnd(); sr.sampleEnd();
} }
return sr; return sr;
} }
public void testAhnx() { public void testAhnx(SydUtils sydUtils) {
orgData = new byte[1024];
//裸签 //裸签
byte[] nakedSign = api.get().SYD_NakedSign(orgData,SM2dn); byte[] nakedSign = sydUtils.SYD_NakedSign(orgData,SM2dn);
//裸签验签 //裸签验签
boolean ver = api.get().SYD_NakedVerify(orgData,nakedSign, SM2dn); boolean ver = sydUtils.SYD_NakedVerify(orgData,nakedSign, SM2dn);
//detach签名 //detach签名
String detachedSign = api.get().detachedSign(orgData, SM2dn); String detachedSign = sydUtils.detachedSign(orgData, SM2dn);
//detach验签 //detach验签
boolean ver1 = api.get().detachedVerify(orgData, detachedSign); boolean ver1 = sydUtils.detachedVerify(orgData, detachedSign);
// testImportCert();
testImportCert();
} }
public void testImportCert() { private void testImportCert(){
String cert = "-----BEGIN CERTIFICATE-----\n" + List<String> masterNodes = Arrays.asList(StringUtils.split(nodes, ";"));
"MIICMDCCAdagAwIBAgIJAOWoGwJCnjlLMAoGCCqBHM9VAYN1MGcxCzAJBgNVBAYT\n" +
"AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdIYWlEaWFuMRMwEQYDVQQK\n" +
"DApHTUNlcnQub3JnMR8wHQYDVQQDDBZHTUNlcnQgR00gUm9vdCBDQSAtIDAxMB4X\n" +
"DTI1MDUxMzAyMzUxM1oXDTI2MDUxMzAyMzUxM1owRTELMAkGA1UEBgwCQ04xCzAJ\n" +
"BgNVBAgMAnp6MQswCQYDVQQHDAJ6ejEMMAoGA1UECgwDenp6MQ4wDAYDVQQDDAV6\n" +
"enp6ejBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABK5fyRSACWPIBBr/3U+qvjvp\n" +
"niropv2PrA3ZLU1bG8vQpwAEMA0kwyqGgXURBPbvWdAhN7s9wfvHbJyMd9CMZGqj\n" +
"gYwwgYkwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCB4AwLAYJYIZIAYb4QgENBB8W\n" +
"HUdNQ2VydC5vcmcgU2lnbmVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSQB7UUqEuG\n" +
"kl4mrx3MAhKTptfbYjAfBgNVHSMEGDAWgBR/Wl47AIRZKg+YvqEObzmVQxBNBzAK\n" +
"BggqgRzPVQGDdQNIADBFAiEA4kgTdn/iA/XYfjTEeOcELwBXd0tTFghkpfP8DhBF\n" +
"KFQCIAXZTL6VPtW67tM/DF4ZgFt5S/YIiFombKa2bWOfL81u\n" +
"-----END CERTIFICATE-----";
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("snmp.target.ip", "172.1.41.191"); map.put("snmp.target.ip", snmpIP);
map.put("snmp.target.port", "162"); map.put("snmp.target.port", snmpPort);
map.put("enterprise.oid", "1.3.6.1.4.1.9999"); map.put("enterprise.oid", snmpOID);
map.put("snmp.community", "public"); map.put("snmp.community", snmpCommunity);
map.put("snmp.version", "1"); map.put("snmp.version", "1");
List<String> masterNodes = new ArrayList<>(); Gson gson = new Gson();
masterNodes.add("172.1.41.139:8889"); String snmpConfig = gson.toJson(map);
String snmpConfig = new Gson().toJson(map);
SydApi4j sydApi4j = new SydApi4j(); SydApi4j sydApi4j = new SydApi4j();
sydApi4j.importCertToServers(masterNodes, 100, cert, "12345678", snmpConfig); String cert21 = convertToPem(Base64.getDecoder().decode(cert));
ImportResult importResult = sydApi4j.importCertToServers(masterNodes, timeout, cert21, "12345678", snmpConfig);
System.out.println("证书导入结果:" + gson.toJson(importResult));
}
private String convertToPem(byte[] derCert){
// 使用Base64编码器(兼容RFC 4648,每行64字符)
StringWriter writer = new StringWriter();
writer.write("-----BEGIN CERTIFICATE-----\n");
// 将DER转换为Base64并分割为每行64字符
String base64Cert = Base64.getMimeEncoder(64, "\n".getBytes()).encodeToString(derCert);
writer.write(base64Cert);
// 如果Base64编码的字符串没有以换行结束,则添加换行
if (!base64Cert.endsWith("\n")) {
writer.write("\n");
}
writer.write("-----END CERTIFICATE-----\n");
return writer.toString();
} }
/** /**
@@ -299,5 +370,9 @@ public class Test4Jemter extends AbstractJavaSamplerClient {
@Override @Override
public void teardownTest(JavaSamplerContext context) { public void teardownTest(JavaSamplerContext context) {
System.runFinalization(); System.runFinalization();
if (api != null) {
api.get().disconnect();
api.remove();
}
} }
} }
+125
View File
@@ -0,0 +1,125 @@
package com.sample;
import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sunyard.SydApiException;
import racal.sunyard.main.SydApi4j;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Test {
private static final String odata = "<?xml version=\"1.0\" encoding=\"utf-8\"?><SignData><TradeType name=\"银行账号转账\" authLevel=\"0\">BankAcctTransfer</TradeType><Timestamp>1710469760912</Timestamp><Fields><AcctType>INNERDEBIT</AcctType><PayerSubAcSeq></PayerSubAcSeq><PayerBankAcType>96</PayerBankAcType><PayerAcNo>6229539600100010640</PayerAcNo><PayerAcName>王二类</PayerAcName><PayerCurrency>156</PayerCurrency><PayeeAcNo name=\"收款人账号:\">6217788308301020599</PayeeAcNo><PayeeAcName name=\"收款人名称:\">王二类</PayeeAcName><Amount name=\"转账金额:\">1</Amount><PayeeBankCode>402/402361018886</PayeeBankCode><PayeeBankName>安徽农金</PayeeBankName><ProvinceCode></ProvinceCode><ProvinceName></ProvinceName><CityCode></CityCode><CityName></CityName><UnionDeptId></UnionDeptId><UnionDeptName></UnionDeptName><TransType>0</TransType><Remark></Remark><Fee>0.00</Fee><CRFlag>1</CRFlag><TransTypeFlag>0</TransTypeFlag><TrsRouteType>0</TrsRouteType><AddPayeeBookFlag>1</AddPayeeBookFlag></Fields></SignData>";
private static String ip1 = null;
private static String ip2 = null;
private static int port = 0;
private static String dn = null;
private static int success = 0;
private static int error = 0;
private static void printInfo(){
System.out.println(String.format("调用总数=%d\t成功总数=%d\t失败总数=%d", success+error, success, error));
}
private static void checkOK(){
success += 1;
printInfo();
}
private static void checkError(){
error += 1;
printInfo();
}
public static void case1(){
SydApi4j.SYD_Set_Parameter_HA(ip1, ip2, port, 3000);
SydApi4j api = (SydApi4j) new SydApi4j();
try {
// 获取签名证书
String cert1 = api.getCertByDn(dn,0);
// 获取加密证书
String cert2 = api.getCertByDn(dn,0);
String odata = "<?xml version=\"1.0\" encoding=\"utf-8\"?><SignData><TradeType name=\"银行账号转账\" authLevel=\"0\">BankAcctTransfer</TradeType><Timestamp>1710469760912</Timestamp><Fields><AcctType>INNERDEBIT</AcctType><PayerSubAcSeq></PayerSubAcSeq><PayerBankAcType>96</PayerBankAcType><PayerAcNo>6229539600100010640</PayerAcNo><PayerAcName>王二类</PayerAcName><PayerCurrency>156</PayerCurrency><PayeeAcNo name=\"收款人账号:\">6217788308301020599</PayeeAcNo><PayeeAcName name=\"收款人名称:\">王二类</PayeeAcName><Amount name=\"转账金额:\">1</Amount><PayeeBankCode>402/402361018886</PayeeBankCode><PayeeBankName>安徽农金</PayeeBankName><ProvinceCode></ProvinceCode><ProvinceName></ProvinceName><CityCode></CityCode><CityName></CityName><UnionDeptId></UnionDeptId><UnionDeptName></UnionDeptName><TransType>0</TransType><Remark></Remark><Fee>0.00</Fee><CRFlag>1</CRFlag><TransTypeFlag>0</TransTypeFlag><TrsRouteType>0</TrsRouteType><AddPayeeBookFlag>1</AddPayeeBookFlag></Fields></SignData>";
byte[] nakedSign = api.SYD_NakedSign(dn, odata.getBytes(), null);
boolean nakedVerify2 = api.SYD_NakedVerifyAll4NX(cert1,4, odata.getBytes(), nakedSign, dn);
api.importCert(cert1.getBytes(), null);
api.importCert(cert2.getBytes(), null);
System.out.println("验签结果:" + nakedVerify2 );
} catch (SydApiException e) {
throw e;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
} finally {
api.disconnect();
}
}
public static void case2(){
SydApi4j.SYD_Set_Parameter_HA(ip1, ip2, port, 3000);
SydApi4j api = (SydApi4j) new SydApi4j();
try {
String sde = api.detachedSignAll(4, odata.getBytes(), dn);
System.out.println("SM2detach签名:"+sde);
boolean bde = api.detachedVerifyAll(4, odata.getBytes(), sde);
System.out.println("SM2detach验签:"+bde);
} finally {
api.disconnect();
}
}
public static void main(String[] args) {
System.out.println("载入配置文件 ./config.json");
String workDir = System.getProperty("user.dir");
Path filePath = Paths.get(workDir,"config.json");
String configStr = FileUtil.readString(filePath.toFile(), StandardCharsets.UTF_8);
JSONObject config = JSONUtil.parseObj(configStr);
ip1 = config.getStr("ip1");
ip2 = config.getStr("ip2");
port = config.getInt("port");
dn = config.getStr("dn");
System.out.println("ip1=" + ip1);
System.out.println("ip2=" + ip2);
System.out.println("port=" + port);
System.out.println("dn=" + dn);
System.out.println("载入配置完成");
System.out.println("开始持续交易, HA 模式,短链接模式");
while (true) {
try {
case1();
checkOK();
Thread.sleep(3000);
// case2();
// checkOK();
// Thread.sleep(3000);
} catch (Exception e) {
System.err.println("发生错误");
e.printStackTrace();
checkError();
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
}
}
@@ -9,7 +9,7 @@ import racal.sunyard.main.SydApi4j;
public class SYMEnDeLongData { public class SYMEnDeLongData {
private SydApi4j api; private SydApi4j api;
private String key = ""; private String sykey = "";
private String keyValue = ""; private String keyValue = "";
private int keyType = 0; private int keyType = 0;
private int inType = 0; private int inType = 0;
@@ -95,11 +95,11 @@ public class SYMEnDeLongData {
public String getKey() { public String getKey() {
return key; return sykey;
} }
public SYMEnDeLongData setKey(String key) { public SYMEnDeLongData setKey(String sykey) {
this.key = key; this.sykey = sykey;
return this; return this;
} }
@@ -138,7 +138,7 @@ public class SydApiException extends RuntimeException{
} }
public SydApiException(String msg, int retCode, boolean flag){ public SydApiException(String msg, int retCode, boolean flag){
super(String.format(" %04X", retCode) + ":" + ( null == msg ? transMsg(retCode) : msg )); super(null == msg ? transMsg(retCode) : msg);
this.retCode = retCode; this.retCode = retCode;
if (null == msg || "".equals(msg)){ if (null == msg || "".equals(msg)){
transMsg(); transMsg();
@@ -0,0 +1,55 @@
package com.sunyard.entity;
import java.util.List;
/**
* 证书导入结果封装类
*/
public class ImportResult {
/** 成功状态码 */
public static final int CODE_SUCCESS = 2000;
/** 部分成功状态码 */
public static final int CODE_PARTIAL_SUCCESS = 2001;
/** 完全失败状态码 */
public static final int CODE_COMPLETE_FAILURE = 2002;
/** 参数错误状态码 */
public static final int CODE_INVALID_PARAM = 4001;
private int code; //返回码
private String certDn; // 证书主题(DN)
private List<String> errCnt; // 详细错误列表(每个失败的服务器)
// 构造方法
public ImportResult() {
}
public ImportResult(int code, String certDn) {
this.code = code;
this.certDn = certDn;
}
// Getters and Setters
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getCertDn() {
return certDn;
}
public void setCertDn(String certDn) {
this.certDn = certDn;
}
public List<String> getErrCnt() {
return errCnt;
}
public void setErrCnt(List<String> errCnt) {
this.errCnt = errCnt;
}
}
@@ -0,0 +1,70 @@
package com.sunyard.util;
import java.util.regex.Pattern;
public class AddressUtil {
// 处理带端口号的地址
public static boolean isValidAddressWithPort(String address) {
if (address == null) {
return false;
}
// 分离 IP:port 或 [IPv6]:port
String[] parts;
if (address.startsWith("[") && address.contains("]:")) {
parts = address.split("\\]:", 2);
parts[0] = parts[0] + "]"; // 补全 IPv6 的括号
} else {
parts = address.split(":", 2);
}
if (parts.length != 2) {
return false;
}
String ipPart = parts[0];
String portPart = parts[1];
return isValidIP(ipPart) &&
isValidPort(portPart);
}
// IPv4 正则(允许 0-255)
private static final Pattern IPV4_PATTERN = Pattern.compile(
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
);
// IPv6 正则(包含缩写形式)
private static final Pattern IPV6_PATTERN = Pattern.compile(
"^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$"
);
// 简化域名正则(允许字母、数字、连字符和点)
private static final Pattern DOMAIN_PATTERN = Pattern.compile(
"^([a-zA-Z0-9-]{1,63}\\.)+[a-zA-Z]{2,63}$"
);
public static boolean isValidIP(String ip) {
// 检查 IPv4 或 IPv6
return IPV4_PATTERN.matcher(ip).matches() ||
IPV6_PATTERN.matcher(ip).matches();
}
public static boolean isValidDomain(String domain) {
return DOMAIN_PATTERN.matcher(domain).matches();
}
public static boolean isValidPort(int port) {
return port >= 0 && port <= 65535;
}
// 字符串形式的端口校验
public static boolean isValidPort(String portStr) {
try {
int port = Integer.parseInt(portStr);
return port >= 0 && port <= 65535;
} catch (NumberFormatException e) {
return false;
}
}
}
+126 -71
View File
@@ -1,6 +1,9 @@
package racal.sunyard.main; package racal.sunyard.main;
import cn.hutool.core.bean.BeanUtil; 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 com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.sunyard.RetWrap; import com.sunyard.RetWrap;
@@ -9,6 +12,7 @@ import com.sunyard.SydApi;
import com.sunyard.SydApiException; import com.sunyard.SydApiException;
import com.sunyard.cert.X509; import com.sunyard.cert.X509;
import com.sunyard.constant.CertUsage; import com.sunyard.constant.CertUsage;
import com.sunyard.entity.ImportResult;
import com.sunyard.entity.Struct; import com.sunyard.entity.Struct;
import com.sunyard.log.ILogFactory; import com.sunyard.log.ILogFactory;
import com.sunyard.log.ILogger; import com.sunyard.log.ILogger;
@@ -54,7 +58,9 @@ import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -81,12 +87,13 @@ public class SydApi4j implements SydApi {
private static int ha_port; private static int ha_port;
private static int ha_timeout; private static int ha_timeout;
private final AtomicBoolean usingBackup = new AtomicBoolean(false); private static final AtomicBoolean usingBackup = new AtomicBoolean(false);
//连接数计数器
private static final AtomicInteger connectionCounter = new AtomicInteger(0);
private final Object reqLock = new Object(); private final Object reqLock = new Object();
private final Lock connectLock = new ReentrantLock();
/** --------------------------主备切换字段--------------------------------------------*/ /** --------------------------主备切换字段--------------------------------------------*/
// 网络失败时重试次数 // 网络失败时重试次数
@@ -128,7 +135,7 @@ public class SydApi4j implements SydApi {
* @param ip2 * @param ip2
* @param port * @param port
* @param timeout * @param timeout
* todo 不应该这样使用 * todo 目前主备切换只适配了安徽农信接口
* @return * @return
*/ */
public static int SYD_Set_Parameter_HA( public static int SYD_Set_Parameter_HA(
@@ -137,12 +144,22 @@ public class SydApi4j implements SydApi {
int port, int port,
int timeout int timeout
) { ) {
Assert.notBlank(ip1, "主机IP不能为空");
Assert.notBlank(ip2, "备机IP不能为空");
Assert.notNull(port, "端口不能为空");
if (!AddressUtil.isValidIP(ip1) || !AddressUtil.isValidIP(ip2)) {
throw new IllegalArgumentException("主备机ip格式有误");
}
if (!AddressUtil.isValidPort(port)) {
throw new IllegalArgumentException("端口范围有误");
}
if (timeout < 0 || timeout > 60000) {
throw new IllegalArgumentException("超时时间范围不正确");
}
SydApi4j.ha_ip1 = ip1; SydApi4j.ha_ip1 = ip1;
SydApi4j.ha_ip2 = ip2; SydApi4j.ha_ip2 = ip2;
SydApi4j.ha_port = port; SydApi4j.ha_port = port;
SydApi4j.ha_timeout = timeout; SydApi4j.ha_timeout = timeout;
return 0; return 0;
} }
@@ -713,19 +730,19 @@ public class SydApi4j implements SydApi {
ByteBuffer readData = null; ByteBuffer readData = null;
int maxRetries = 2; int maxRetries = 2;
int retryCount = 0; int retryCount = 0;
while (retryCount <= maxRetries) { while (retryCount < maxRetries) {
try { try {
synchronized(reqLock) { synchronized(reqLock) {
byte[] sentData = this.syncSend(data); byte[] sentData = this.syncSend(data);
readData = this.syncRead(sentData); readData = this.syncRead(sentData);
break; return readData;
} }
} catch (SydApiException e) { } catch (SydApiException e) {
handleNetworkFailure(e, retryCount, maxRetries); // 统一处理网络故障 handleNetworkFailure(e, retryCount, maxRetries); // 统一处理网络故障
retryCount ++; retryCount ++;
} }
} }
return readData; throw new SydApiException("加密机连接失败,主备节点均不可用", -1);
} }
public byte[] SYD_NakedSign_OuterHash(byte[] orgData, String sCertDN) { public byte[] SYD_NakedSign_OuterHash(byte[] orgData, String sCertDN) {
@@ -858,10 +875,11 @@ public class SydApi4j implements SydApi {
data.put("returnSign$option", 0); data.put("returnSign$option", 0);
ByteBuffer bb = proto.rend(packet); ByteBuffer bb = proto.rend(packet);
synchronized(this) { // synchronized(this) {
byte[] b = this.syncSend(bb); // byte[] b = this.syncSend(bb);
bb = this.syncRead(b); // bb = this.syncRead(b);
} // }
bb = sendAndGetResponse(bb);
Packet p = proto.parse(bb, packet); Packet p = proto.parse(bb, packet);
Map<String, Object> ret = p.toMap(); Map<String, Object> ret = p.toMap();
@@ -875,6 +893,7 @@ public class SydApi4j implements SydApi {
if ((be[0] ^ be[1]) != 0) { if ((be[0] ^ be[1]) != 0) {
SydApiException e = new SydApiException(error.getInfo(), error.autoInt()); SydApiException e = new SydApiException(error.getInfo(), error.autoInt());
println("验签失败=" + e.toString()); println("验签失败=" + e.toString());
log.info("验签失败:{}", e.toString());
return false; return false;
} else { } else {
return true; return true;
@@ -1345,10 +1364,13 @@ public class SydApi4j implements SydApi {
} }
public String importCertToServers(List<String> addressList, int timeout, String cert, String bkCode, String snmpConfig) { public ImportResult importCertToServers(List<String> addressList, int timeout, String cert, String bkCode, String snmpConfig) {
if (null == addressList || addressList.isEmpty()) { if (null == addressList || addressList.isEmpty()) {
throw new IllegalArgumentException("签名服务器地址不能为空"); throw new IllegalArgumentException("签名服务器地址不能为空");
} }
if (addressList.size() > 50) {
throw new IllegalArgumentException("签名服务器地址数量不大于50");
}
if (null == cert || cert.length() == 0) { if (null == cert || cert.length() == 0) {
throw new IllegalArgumentException("证书不能为空"); throw new IllegalArgumentException("证书不能为空");
} }
@@ -1356,7 +1378,7 @@ public class SydApi4j implements SydApi {
throw new IllegalArgumentException("snmp配置不能为空"); throw new IllegalArgumentException("snmp配置不能为空");
} }
List<TaskContext<String>> taskContexts = List<TaskContext<String>> taskContexts =
addressList.stream().map(p -> createTaskContext(p, timeout, cert)).collect(Collectors.toList()); addressList.stream().distinct().map(p -> createTaskContext(p, timeout, cert)).collect(Collectors.toList());
AsyncTaskExecutor executor = new AsyncTaskExecutor(); AsyncTaskExecutor executor = new AsyncTaskExecutor();
List<TaskOutcome<String>> taskOutcomes = executor.execBatchTasks(taskContexts); List<TaskOutcome<String>> taskOutcomes = executor.execBatchTasks(taskContexts);
executor.shutdown(); executor.shutdown();
@@ -1379,17 +1401,20 @@ public class SydApi4j implements SydApi {
} catch (Exception e) { } catch (Exception e) {
log.warn("导入证书格式错误!"); log.warn("导入证书格式错误!");
} }
ImportResult importResult = new ImportResult();
importResult.setCertDn(dn);
Gson gson = new Gson();
if (!failures.isEmpty()) { if (!failures.isEmpty()) {
//记录失败日志 //记录失败日志
stringBuilder.append("行号:").append(bkCode).append("\n").append("DN:").append(dn) stringBuilder.append("行号:").append(bkCode).append("\n").append("DN:").append(dn)
.append("\n序列号:").append(serialNumber).append("\n证书:").append(cert); .append("\n序列号:").append(serialNumber).append("\n证书:").append(cert);
log.warn("证书导入失败!\n{}", stringBuilder); log.warn("证书导入失败!\n{}", stringBuilder);
System.out.println("证书导入失败!" + stringBuilder);
//异步发送snmp trap消息 //异步发送snmp trap消息
String result = "[" + failures.stream() String result = "[" + failures.stream()
.map(Object::toString) .map(Object::toString)
.collect(Collectors.joining(",")) + "]"; .collect(Collectors.joining(",")) + "]";
String message = "支付签名证书导入失败!签名服务器地址:" + result + "| 证书对应行号:[" + bkCode + "]"; String message = "支付签名证书导入失败!签名服务器地址:" + result + "| 证书对应行号:[" + bkCode + "]";
Gson gson = new Gson();
Map<String, String> map = gson.fromJson(snmpConfig, new TypeToken<Map<String, String>>() {}.getType()); Map<String, String> map = gson.fromJson(snmpConfig, new TypeToken<Map<String, String>>() {}.getType());
try (SnmpTrapSender sender = new SnmpTrapSender(map)) { try (SnmpTrapSender sender = new SnmpTrapSender(map)) {
sender.sendTrap(message, 2); sender.sendTrap(message, 2);
@@ -1397,8 +1422,16 @@ public class SydApi4j implements SydApi {
} catch (Exception e) { } catch (Exception e) {
log.warn("snmp告警消息发送失败:{}", e.getMessage()); log.warn("snmp告警消息发送失败:{}", e.getMessage());
} }
importResult.setErrCnt(failures);
if (failures.size() == addressList.size()) {
importResult.setCode(ImportResult.CODE_COMPLETE_FAILURE);
} else {
importResult.setCode(ImportResult.CODE_PARTIAL_SUCCESS);
}
} else {
importResult.setCode(ImportResult.CODE_SUCCESS);
} }
return dn; return importResult;
} }
private TaskContext<String> createTaskContext(String address, int timeout, String cert) { private TaskContext<String> createTaskContext(String address, int timeout, String cert) {
@@ -1409,6 +1442,9 @@ public class SydApi4j implements SydApi {
private String importCertToServer(String address, int timeout, String cert) { private String importCertToServer(String address, int timeout, String cert) {
//address 格式为 ip:port,拆分成ip和port,需要进行格式判断 //address 格式为 ip:port,拆分成ip和port,需要进行格式判断
if (!AddressUtil.isValidAddressWithPort(address)) {
throw new IllegalArgumentException("地址格式有误:" + address);
}
String[] addressParts = address.split(":"); String[] addressParts = address.split(":");
String ip = addressParts[0]; String ip = addressParts[0];
int port = Integer.parseInt(addressParts[1]); int port = Integer.parseInt(addressParts[1]);
@@ -2354,22 +2390,26 @@ public class SydApi4j implements SydApi {
* 连接或重连到有效节点 * 连接或重连到有效节点
*/ */
public synchronized void connectHa() { public synchronized void connectHa() {
// 优先尝试主节点 // 优先尝试主节点
if (!usingBackup.get()) { if (!usingBackup.get()) {
if (tryConnect(ha_ip1)) { if (tryConnect(ha_ip1)) {
System.out.println("连接到主节点: " + ha_ip1); log.info("连接到主节点,ip:{}", ha_ip1);
return; // System.out.println("连接到主节点,ip:" + ha_ip1);
}
}
// 连接到备节点
if (tryConnect(ha_ip2)) {
System.out.println("连接到备节点: " + ha_ip2);
usingBackup.set(true);
return; return;
} }
}
throw new SydApiException("所有节点均不可用", -100); // 连接到备节点
if (tryConnect(ha_ip2)) {
log.info("连接到备节点,ip:{}", ha_ip2);
// System.out.println("连接到备节点,ip:" + ha_ip2);
// usingBackup.set(true);
usingBackup.compareAndSet(false, true);
return;
}
throw new SydApiException("节点连接异常", -100);
} }
/** /**
@@ -2382,50 +2422,49 @@ public class SydApi4j implements SydApi {
if (ha_timeout > 0) { if (ha_timeout > 0) {
newSocket.connect(address, ha_timeout); newSocket.connect(address, ha_timeout);
newSocket.setSoTimeout(ha_timeout);
} else { } else {
newSocket.connect(address); newSocket.connect(address);
} }
newSocket.setSoTimeout(ha_timeout);
// 关闭旧socket(如果存在) // 关闭旧socket(如果存在)
safeClose(); safeClose();
this.socket = newSocket; this.socket = newSocket;
return true; return true;
} catch (IOException e) { } catch (IOException e) {
System.out.println("节点连接失败: " + ip + " - " + e.getMessage()); log.info("节点连接失败,ip:{}/exception:{}", ip, e.getMessage());
return false; return false;
} }
} }
private synchronized void handleNetworkFailure(Exception e, int retryCount, int maxRetries) { private synchronized void handleNetworkFailure(Exception e, int retryCount, int maxRetries) {
if (retryCount > maxRetries) { if (retryCount > maxRetries) {
System.out.println(Thread.currentThread().getName() + "重试次数耗尽");
return; return;
} }
StopWatch stopWatch = new StopWatch();
System.out.printf("线程[%s]网络故障,尝试切换节点 (重试: %d/%d)%n", stopWatch.start();
Thread.currentThread().getName(), retryCount + 1, maxRetries); log.info("socket收发信息异常,准备重试:{}/当前重试:{}次", e.getMessage(),retryCount + 1);
System.out.println(DateTime.now() + "/socket收发信息异常:" + e.getMessage() + ",准备重试, 当前重试:" + ++retryCount + "次");
boolean currentState = usingBackup.get(); boolean currentState = usingBackup.get();
boolean newState = !currentState; boolean newState = !currentState;
if (usingBackup.compareAndSet(currentState, newState)) { if (usingBackup.compareAndSet(currentState, newState)) {
String targetIp = newState ? ha_ip2 : ha_ip1; String targetIp = newState ? ha_ip2 : ha_ip1;
System.out.println("全局节点切换: " + (currentState ? "备机" : "主机") + "→" +
(newState ? "备机" : "主机"));
try { try {
safeClose(); safeClose();
connect(targetIp, ha_port, ha_timeout); connect(targetIp, ha_port, ha_timeout);
System.out.println("线程[" + Thread.currentThread().getName() + "]连接重建成功"); System.out.println("故障节点切换成功,当前使用:" + targetIp);
log.info("故障节点切换成功,当前使用ip:{}", targetIp);
} catch (Exception ex) { } catch (Exception ex) {
System.out.println("线程[" + Thread.currentThread().getName() + "]节点切换失败: " + ex.getMessage());
usingBackup.compareAndSet(newState, currentState); usingBackup.compareAndSet(newState, currentState);
} }
} else { } else {
System.out.println("线程[" + Thread.currentThread().getName() + "]节点已被其他线程切换,使用新节点"); System.err.println("线程[" + Thread.currentThread().getName() + "]节点已被其他线程切换,使用新节点");
} }
stopWatch.stop();
log.info("节点切换时间:{}", stopWatch.getTotalTimeMillis());
System.out.println("节点切换时间:" + stopWatch.getTotalTimeMillis() + "ms");
} }
private void safeClose() { private void safeClose() {
@@ -2433,7 +2472,7 @@ public class SydApi4j implements SydApi {
try { try {
socket.close(); socket.close();
} catch (IOException e) { } catch (IOException e) {
System.out.println("关闭连接异常: " + e.getMessage()); System.err.println("关闭连接异常: " + e.getMessage());
} }
socket = null; socket = null;
} }
@@ -2477,7 +2516,7 @@ public class SydApi4j implements SydApi {
// 发送失败 // 发送失败
if (null != ha_ip2) { if (null != ha_ip2) {
// HA 模式直接失败 // HA 模式直接失败
e.printStackTrace(); // e.printStackTrace();
throw new SydApiException("Socket write error", -2); throw new SydApiException("Socket write error", -2);
} else { } else {
// 非 HA 模式检查重试 // 非 HA 模式检查重试
@@ -2633,15 +2672,16 @@ public class SydApi4j implements SydApi {
private void connect(String ip, int port, int timeout) { private void connect(String ip, int port, int timeout) {
synchronized (reqLock) { synchronized (reqLock) {
safeClose(); safeClose();
try { try {
Socket newSocket = new Socket(); Socket newSocket = new Socket();
SocketAddress address = new InetSocketAddress(ip, port); SocketAddress address = new InetSocketAddress(ip, port);
newSocket.connect(address, timeout); if (timeout > 0) {
newSocket.setSoTimeout(timeout); newSocket.connect(address, timeout);
newSocket.setSoTimeout(timeout);
} else {
newSocket.connect(address);
}
this.socket = newSocket; this.socket = newSocket;
System.out.printf("线程[%s]连接到%s:%d%n",
Thread.currentThread().getName(), ip, port);
} catch (IOException e) { } catch (IOException e) {
throw new SydApiException("连接失败: " + ip + ":" + port, -2, e); throw new SydApiException("连接失败: " + ip + ":" + port, -2, e);
} }
@@ -2650,7 +2690,17 @@ public class SydApi4j implements SydApi {
@Override @Override
synchronized public SydApi connect(String ip, int port, String pwd, int timeout) { synchronized public SydApi connect(String ip, int port, String pwd, int timeout) {
Assert.notBlank(ip, "IP不能为空");
Assert.notNull(port, "端口不能为空");
if (!AddressUtil.isValidIP(ip)) {
throw new IllegalArgumentException("ip格式有误");
}
if (!AddressUtil.isValidPort(port)) {
throw new IllegalArgumentException("端口范围有误");
}
if (timeout < 0 || timeout > 60000) {
throw new IllegalArgumentException("超时时间范围不正确");
}
// if (null != ha_ip2) { // if (null != ha_ip2) {
// throw new SydApiException("双机热备模式不用调用此方法", -1); // throw new SydApiException("双机热备模式不用调用此方法", -1);
// } // }
@@ -2660,10 +2710,10 @@ public class SydApi4j implements SydApi {
try { try {
if (timeout > 0) { if (timeout > 0) {
socket.connect(address, timeout); socket.connect(address, timeout);
socket.setSoTimeout(timeout);
} else { } else {
socket.connect(address); socket.connect(address);
} }
socket.setSoTimeout(timeout);
} catch (Exception e) { } catch (Exception e) {
socket = reConnect(new SydApiException(-2, e)); socket = reConnect(new SydApiException(-2, e));
} }
@@ -2739,7 +2789,6 @@ public class SydApi4j implements SydApi {
while (this.retryWhenNetError > 0) { while (this.retryWhenNetError > 0) {
try { try {
println("Net error retry on " + this.retryWhenNetError); println("Net error retry on " + this.retryWhenNetError);
System.out.println("Net error retry on ");
Socket socket = new Socket(); Socket socket = new Socket();
SocketAddress address = new InetSocketAddress(ip, port); SocketAddress address = new InetSocketAddress(ip, port);
@@ -3944,10 +3993,12 @@ public class SydApi4j implements SydApi {
// 渲染发送 耗时长 // 渲染发送 耗时长
ByteBuffer bb = proto.rend(packet); ByteBuffer bb = proto.rend(packet);
synchronized (this) { // synchronized (this) {
// 响应解析 // // 响应解析
bb = syncRead(syncSend(bb)); // bb = syncRead(syncSend(bb));
} // }
bb = sendAndGetResponse(bb);
//ProtocolParser parser = pset.getProtocolResParse(); //ProtocolParser parser = pset.getProtocolResParse();
Packet p = proto.parse(bb); Packet p = proto.parse(bb);
@@ -4177,10 +4228,12 @@ public class SydApi4j implements SydApi {
bb.put((byte) 0x31); bb.put((byte) 0x31);
} }
synchronized (this) { // synchronized (this) {
// 响应解析 // // 响应解析
bb = syncRead(syncSend(bb)); // bb = syncRead(syncSend(bb));
} // }
bb = sendAndGetResponse(bb);
byte[] success = new byte[2]; byte[] success = new byte[2];
Arrays.fill(success, (byte) 0); Arrays.fill(success, (byte) 0);
@@ -4678,10 +4731,12 @@ public class SydApi4j implements SydApi {
// 渲染发送 // 渲染发送
ByteBuffer bb = proto.rend(packet); ByteBuffer bb = proto.rend(packet);
synchronized (this) { // synchronized (this) {
// 响应解析 // // 响应解析
bb = syncRead(syncSend(bb)); // bb = syncRead(syncSend(bb));
} // }
bb = sendAndGetResponse(bb);
//ProtocolParser parser = pset.getProtocolResParse(); //ProtocolParser parser = pset.getProtocolResParse();
Packet p = proto.parse(bb); Packet p = proto.parse(bb);
@@ -8998,7 +9053,7 @@ public class SydApi4j implements SydApi {
keyTpye = "008"; keyTpye = "008";
} }
String key = "XK"; String xkkey = "XK";
// 机构号扩展到 16 位 // 机构号扩展到 16 位
// 前补 0 // 前补 0
@@ -9007,10 +9062,10 @@ public class SydApi4j implements SydApi {
String kid = "00000"; String kid = "00000";
String v = String.format("%03d", Version); String v = String.format("%03d", Version);
key += gid + keyTpye + kid + v; xkkey += gid + keyTpye + kid + v;
data.put("MACData", Util.bytes2HexString(Data).getBytes()); data.put("MACData", Util.bytes2HexString(Data).getBytes());
data.put("key", key); data.put("key", xkkey);
data.put("full", fullFlag); data.put("full", fullFlag);
data.put("macLen", macLenFlag); data.put("macLen", macLenFlag);
@@ -9076,7 +9131,7 @@ public class SydApi4j implements SydApi {
keyTpye = "008"; keyTpye = "008";
} }
String key = "XK"; String xkkey = "XK";
// 机构号扩展到 16 位 // 机构号扩展到 16 位
// 前补 0 // 前补 0
@@ -9085,12 +9140,12 @@ public class SydApi4j implements SydApi {
String kid = "00000"; String kid = "00000";
String v = String.format("%03d", Version); String v = String.format("%03d", Version);
key += gid + keyTpye + kid + v; xkkey += gid + keyTpye + kid + v;
data.put("MAC", mac); data.put("MAC", mac);
data.put("MACData", Util.bytes2HexString(Data).getBytes()); data.put("MACData", Util.bytes2HexString(Data).getBytes());
data.put("key", key); data.put("key", xkkey);
data.put("full", fullFlag); data.put("full", fullFlag);
data.put("macLen", macLenFlag); data.put("macLen", macLenFlag);
+328 -97
View File
@@ -1,18 +1,22 @@
package sample; package sample;
import cn.hutool.core.date.StopWatch; import cn.hutool.core.date.StopWatch;
import cn.hutool.core.date.Week; import com.Sample.SydUtils;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.SydApiException; import com.sunyard.SydApiException;
import com.sunyard.entity.ImportResult;
import com.sunyard.proto.Util; import com.sunyard.proto.Util;
import com.sunyard.snmp.SnmpTrapSender; import com.sunyard.util.CertUtil;
import com.sunyard.util.IpLockUtils; import com.sunyard.util.IpLockUtils;
import org.bouncycastle.util.encoders.Hex;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import racal.sunyard.main.SydApi4j; import racal.sunyard.main.SydApi4j;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
@@ -25,18 +29,13 @@ public class Test4NongxinCW {
final String SM2dn = "C=CN,ST=zz,L=zz,O=zzz,CN=zzzzz"; final String SM2dn = "C=CN,ST=zz,L=zz,O=zzz,CN=zzzzz";
byte[] orgData = new byte[100]; byte[] orgData = new byte[1024];
@Before @Before
public void before() { public void before() {
//主备调用接口 //主备调用接口
SydApi4j.SYD_Set_Parameter_HA("172.1.41.96", "172.1.41.139", 8889, 1000); SydApi4j.SYD_Set_Parameter_HA("172.1.41.139", "172.1.41.96", 8889, 3000);
api = (SydApi4j) new SydApi4j(); api = (SydApi4j) new SydApi4j();
// api.startHeartbeat();
// 通过设置debug的属性开启debug,如果不设置则默认不打开
// api = (SydApi4j) new SydApi4j().connect("172.1.41.139", 8891, null, 1000);
} }
@Test @Test
@@ -55,46 +54,55 @@ public class Test4NongxinCW {
@Test @Test
public void testHA() { public void testHA() {
// byte[] nakedSign1 = api.SYD_NakedSignAll(4,orgData, SM2dn);
for (int i = 0; i < 10000; i++) { // System.out.println("SM2大数据裸签:"+ Util.bytes2HexString(nakedSign1));
// boolean nakedVerify1 = api.SYD_NakedVerifyAll(4,orgData, nakedSign1, SM2dn);
// System.out.println("SM2数据验签:"+nakedVerify1 );
// for (int i = 0; i < 10000; i++) {
byte[] nakedSign = api.SYD_NakedSign(orgData,SM2dn); byte[] nakedSign = api.SYD_NakedSign(orgData,SM2dn);
} System.out.println("SM2签名:"+ Util.encodeBase64(nakedSign));
byte[] nakedSign1 = api.SYD_NakedSignAll(4,orgData, SM2dn);
// System.out.println("SM2大数据裸签:"+ Util.bytes2HexString(nakedSign1));
// boolean nakedVerify1 = api.SYD_NakedVerifyAll(4,orgData, nakedSign1, SM2dn);
// System.out.println("SM2数据验签:"+nakedVerify1 );
// }
} }
/**
* 长连接性能测试
* @throws InterruptedException
* @throws ExecutionException
*/
@Test @Test
public void tes() throws InterruptedException, ExecutionException { public void testPerformance() throws InterruptedException, ExecutionException {
// 配置HA参数 // 创建200个线程并发操作API
// SydApi4j.SYD_Set_Parameter_HA("172.1.41.139", "172.1.41.96", 8889, 1000); ExecutorService executor = Executors.newFixedThreadPool(10);
// 创建20个线程并发操作API
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<?>> futures = new ArrayList<>(); List<Future<?>> futures = new ArrayList<>();
// 模拟主节点故障
CountDownLatch startLatch = new CountDownLatch(1); CountDownLatch startLatch = new CountDownLatch(1);
for (int i = 0; i < 20; i++) { for (int i = 0; i < 10; i++) {
futures.add(executor.submit(() -> { futures.add(executor.submit(() -> {
try {
startLatch.await(); // 等待统一开始
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
SydApi4j api2 = new SydApi4j(); SydApi4j api2 = new SydApi4j();
for (int j = 0; j < 10000; j++) { for (int j = 0; j < 10000; j++) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
byte[] nakedSign = api2.SYD_NakedSign(orgData,SM2dn); byte[] nakedSign = api2.SYD_NakedSign(orgData,SM2dn);
stopWatch.stop();
// System.out.println("p1签名耗时---:" + stopWatch.getLastTaskTimeMillis() + "ms");
// stopWatch.start();
// String sign = "304502204ACEE7FA06644B6EAE62E5FBF824B6ED8D4432D5CE52580381ECF3570DE032F4022100F30DF2B902A3C34E183498C14565D03C9F28FD1BCCDFB557B52996539BCCF58F";
// boolean ver = api2.SYD_NakedVerify(orgData,nakedSign, SM2dn);
// stopWatch.stop();
// System.out.println("p1验签耗时:" + stopWatch.getLastTaskTimeMillis() + "ms");
} }
api2.disconnect();
})); }));
} }
// 触发所有线程开始 // 触发所有线程开始
startLatch.countDown(); startLatch.countDown();
// 随机触发主节点故障(模拟网络中断)
Thread.sleep(500); Thread.sleep(500);
// 等待所有任务完成 // 等待所有任务完成
for (Future<?> future : futures) { for (Future<?> future : futures) {
future.get(); future.get();
@@ -103,20 +111,69 @@ public class Test4NongxinCW {
executor.shutdown(); executor.shutdown();
} }
/**
* 短连接性能测试
* @throws InterruptedException
* @throws ExecutionException
*/
@Test
public void testUtils() throws InterruptedException, ExecutionException {
// 创建200个线程并发操作API
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Future<?>> futures = new ArrayList<>();
CountDownLatch startLatch = new CountDownLatch(1);
for (int i = 0; i < 20; i++) {
futures.add(executor.submit(() -> {
for (int j = 0; j < 1000; j++) {
StopWatch stopWatch = new StopWatch();
SydUtils sydUtils = new SydUtils("172.1.41.139", "172.1.41.96", 8889, 3000);
stopWatch.start();
byte[] nakedSign = sydUtils.SYD_NakedSign(orgData,SM2dn);
stopWatch.stop();
System.out.println("p1签名耗时---:" + stopWatch.getLastTaskTimeMillis() + "ms");
stopWatch.start();
boolean ver = sydUtils.SYD_NakedVerify(orgData,nakedSign, SM2dn);
stopWatch.stop();
System.out.println("p1验签耗时:" + stopWatch.getLastTaskTimeMillis() + "ms");
sydUtils.disconnect();
}
}));
}
// 触发所有线程开始
startLatch.countDown();
Thread.sleep(500);
// 等待所有任务完成
for (Future<?> future : futures) {
future.get();
}
executor.shutdown();
}
@Test @Test
public void nakeSign(){ public void nakeSign(){
String ori = "2025071700064382|2025-06-21T15:39:47|102100088898|102100088898|402361018886|402361018886|BEPS|DM00|202507170013|010000|123456789123456789|1|2025071700064387|王二|地址908|6232208340101760984|402361018886|402361018886|CNY0.05|";
System.out.println(Util.encodeBase64(ori.getBytes(StandardCharsets.UTF_8)));
String signValue = "MEYCIQDdG83MV2zyX2ZboKKUKZX+8qHr3ZfmxlBY7gElqEQZsAIhAPXjePjHfjChP0Rdlsf4PU9eJN7Lbl29nrHCQ7NzhZOV";
byte[] s = Util.decodeBase64(signValue);
System.out.println(Util.bytes2HexString(s));
// String SM2dn1 = "C=CN,ST=3,L=3,O=3,OU=3,OU=3,CN=3"; // String SM2dn1 = "C=CN,ST=3,L=3,O=3,OU=3,OU=3,CN=3";
// orgData = Hex.decode("80a370b809e8a46ba51211a35d6f0180fea32b4acc97916bc9c517ea6651134c"); // orgData = Hex.decode("80a370b809e8a46ba51211a35d6f0180fea32b4acc97916bc9c517ea6651134c");
// byte[] nakedSign1 = api.SYD_NakedSign(SM2dn, (byte[])null, orgData); // byte[] nakedSign1 = api.SYD_NakedSign(SM2dn, (byte[])null, orgData);
// System.out.println("SM2签名:"+ Util.bytes2HexString(nakedSign1)); // System.out.println("SM2签名:"+ Util.bytes2HexString(nakedSign1));
orgData = new byte[4096]; // String dn ="C=cn,O=CFCA CS OCA11,OU=CNAPS,OU=Enterprises,CN=041@Z313641099995@BHN@00000010";
//裸签 // orgData = "123456".getBytes();
byte[] nakedSign = api.SYD_NakedSign(orgData,SM2dn); //
System.out.println("SM2签名:"+ Util.bytes2HexString(nakedSign)); // //裸签
//裸签验签 // byte[] nakedSign = api.SYD_NakedSign(orgData, SM2dn);
boolean ver = api.SYD_NakedVerify(orgData,nakedSign, SM2dn); // System.out.println("SM2签名:"+ Util.bytes2HexString(nakedSign));
System.out.println("SM2验签:"+ ver); // System.out.println(Util.encodeBase64(nakedSign));
// //裸签验签
//
// String sign = "30450220400849D815EE6C73A6D7334D76EF6076452367E444BBF902B4278A0D7C9843C302210095086DDC9A42E53ABCD0B172BA6A9A9814AEA580C19CDD229ABD3277321984C1";
// boolean ver = api.SYD_NakedVerify(orgData, nakedSign, SM2dn);
// System.out.println("SM2验签:"+ ver);
} }
@Test @Test
@@ -133,14 +190,18 @@ public class Test4NongxinCW {
@Test @Test
public void detSign(){ public void detSign(){
orgData = new byte[4096]; orgData = new byte[1024];
//detach签名 byte[] orgData1 = "12345678".getBytes(StandardCharsets.UTF_8);
String detachedSign = api.detachedSign(orgData, SM2dn); // for (int i = 0; i < 10000; i++) {
System.out.println("detach签名:"+ detachedSign); //detach签名
String detachedSign = api.detachedSign(orgData1, SM2dn);
System.out.println("detach签名:"+ detachedSign);
//detach验签
boolean ver = api.detachedVerify(orgData1, detachedSign);
System.out.println("detach验签:"+ ver);
// }
//detach验签
boolean ver = api.detachedVerify(orgData, detachedSign);
System.out.println("detach验签:"+ ver);
} }
@@ -261,8 +322,13 @@ public class Test4NongxinCW {
List<Thread> threads = new ArrayList<>(); List<Thread> threads = new ArrayList<>();
// 创建100个线程 // 创建100个线程
for (int i = 0; i < 200; i++) { for (int i = 0; i < 20; i++) {
Thread thread = new Thread(this::importAllCert); Thread thread = new Thread(() -> {
for (int j = 0; j < 1000; j++) {
api.SYD_NakedSign(orgData,SM2dn);
importAllCert();
}
});
thread.start(); thread.start();
threads.add(thread); threads.add(thread);
} }
@@ -272,7 +338,7 @@ public class Test4NongxinCW {
thread.join(); thread.join();
} }
System.out.println(IpLockUtils.getLockStatus("172.1.41.96:8889")); System.out.println(IpLockUtils.getLockStatus("172.1.41.139:8889"));
System.out.println("所有线程执行完毕"); System.out.println("所有线程执行完毕");
} }
@@ -281,6 +347,103 @@ public class Test4NongxinCW {
public void importAllCert() { public void importAllCert() {
StopWatch stopWatch = new StopWatch(); StopWatch stopWatch = new StopWatch();
stopWatch.start(); stopWatch.start();
String cert = "-----BEGIN CERTIFICATE-----\n" +
"MIIC2TCCAn2gAwIBAgIFIGh5YWAwDAYIKoEcz1UBg3UFADBdMQswCQYDVQQGEwJD\n" +
"TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y\n" +
"aXR5MRwwGgYDVQQDDBNDRkNBIFRFU1QgU00yIE9DQTExMB4XDTI0MDQwOTAxMTAy\n" +
"M1oXDTI1MTEzMDAxMTAyM1owgY4xCzAJBgNVBAYTAmNuMR8wHQYDVQQKDBZDRkNB\n" +
"IENTIFRFU1QgU00yIE9DQTExMQ0wCwYDVQQLDARERU1QMRkwFwYDVQQLDBBPcmdh\n" +
"bml6YXRpb25hbC0xMTQwMgYDVQQDDCswNTFAM0MzMTIyOTM0MDAwMDE0QEMzMTIy\n" +
"OTM0MDAwMDE0QDAwMDAwMDAxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEyW/R\n" +
"iEfheoKHHf8UGA8D8dMRIKiGr1M3kId/f1mfWsTX/BTH8+FmruZxfGZAXcSGcn5Z\n" +
"gR582ck7YO2bhDcap6OB9TCB8jAfBgNVHSMEGDAWgBS+pn5NPXyPoFXmwS8JLiwg\n" +
"Q7NCfzBIBgNVHSAEQTA/MD0GCGCBHIbvKgECMDEwLwYIKwYBBQUHAgEWI2h0dHA6\n" +
"Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTUuaHRtMDoGA1UdHwQzMDEwL6AtoCuG\n" +
"KWh0dHA6Ly8yMTAuNzQuNDIuMy9PQ0ExMS9TTTIvY3JsMjkyNzMuY3JsMAsGA1Ud\n" +
"DwQEAwID6DAdBgNVHQ4EFgQU1K07X7clXMkYBI3JblkykKilnskwHQYDVR0lBBYw\n" +
"FAYIKwYBBQUHAwIGCCsGAQUFBwMEMAwGCCqBHM9VAYN1BQADSAAwRQIhAL8uWl4K\n" +
"hUEIUnSsM0RlUn4aSkK3R0QFpqdBu7AYCtXcAiB5tIOkP1ycAtp0W3mSHPabAgUq\n" +
"dHXEO3AzKABKxIAH7Q==\n" +
"-----END";
List<String> masterNodes = new ArrayList<>();
// masterNodes.add("172.16.18.99:8889");
// masterNodes.add("172.16.18.5:8889");
masterNodes.add("172.1.41.139:8889");
// masterNodes.add("172.1.41.196:8889333");
// masterNodes.add("172.16.18.89");
// masterNodes.add("172.16.18.89");
int timeout = 3000;
Map<String, String> map = new HashMap<>();
map.put("snmp.target.ip", "172.1.41.191");
map.put("snmp.target.port", "162");
map.put("enterprise.oid", "1.3.6.1.4.1.9999");
map.put("snmp.community", "public");
map.put("snmp.version", "1");
Gson gson = new Gson();
String snmpConfig = gson.toJson(map);
SydApi4j sydApi4j = new SydApi4j();
ImportResult result = sydApi4j.importCertToServers(masterNodes, timeout, cert, "12345678", snmpConfig);
System.out.println(gson.toJson(result));
System.out.println(result.getCode());
System.out.println(gson.toJson(result.getErrCnt()));
System.out.println(result.getCertDn());
stopWatch.stop();
System.out.println(stopWatch.getTotalTimeSeconds());
}
@Test
public void delCert() {
String SM2dn1 = "C=CN,ST=北京,L=北京,O=信雅达,OU=测试部门1,CN=172.1.41.139";
boolean del = api.deleteCert(SM2dn1);
System.out.println("删除:"+ del);
}
@Test
public void selectCert() throws Exception {
String SM2dn1 = "C=CN,ST=2,L=3,O=3,OU=1,OU=1,CN=qwqq";
String dn = "C=CN,ST=2,L=3,O=3,OU=1,CN=qwqq";
String dn1 = "C=cn,O=CFCA CS OCA11,OU=CNAPS,OU=Enterprises,CN=041@Z313641099995@BHN@00000010";
String dn2 = "C=cn,O=CFCA TEST OCA1,OU=DEMP,OU=Organizational-1,CN=041@ZDEMP@DEMP@00000001";
// String s = api.getCertByDn(dn1);
String s = api.getCertByDn(dn1.getBytes());
System.out.println(s);
String message = "sdas发顺丰";
byte[] gbkBytes = message.getBytes("GBK");
System.out.println("GBK Encoded Bytes: " + Arrays.toString(gbkBytes));
// Decoding back to String
String decodedMessage = new String(gbkBytes, "GBK");
System.out.println("Decoded Message: " + decodedMessage);
}
@Test
public void selCert() throws Exception {
// String certBase64 = "MIICujCCAl6gAwIBAgIFEFeGNUIwDAYIKoEcz1UBg3UFADBcMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTEwHhcNMjMxMDI2MDYwMDU5WhcNMjgxMDI2MDYwMDU5WjByMQswCQYDVQQGEwJjbjEXMBUGA1UECgwOQ0ZDQSBURVNUIE9DQTExDTALBgNVBAsMBERFTVAxGTAXBgNVBAsMEE9yZ2FuaXphdGlvbmFsLTExIDAeBgNVBAMMFzA0MUBaREVNUEBERU1QQDAwMDAwMDAxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE3NOLwnCvPxeZxS5lUSl+fxojdYwV1mD5eDGOkPeATl88oW0Q1PuBd0aQ29HmufRamZb2BlfLhjcgS5TsKlX4qqOB9DCB8TAfBgNVHSMEGDAWgBRr/hjaj0I6prhtsy6Igzo0osEw4TBIBgNVHSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTQuaHRtMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly91Y3JsLmNmY2EuY29tLmNuL1NNMi9jcmw1Mzg2My5jcmwwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSElGKzsZJ04RMd60sFqiHpxl9/njAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDAYIKoEcz1UBg3UFAANIADBFAiEAjmCCIlDNdXw0qRZe7oYrkel4wTpg++c/C+MKLbPfRpgCIEVyrM68qeuVmaFZ5ZA3TtUXQg1RYQjz/5yhl/3jhdQ9";
// String s = "MIICzDCCAnCgAwIBAgIFIGdEBSgwDAYIKoEcz1UBg3UFADBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQDDBNDRkNBIFRFU1QgU00yIE9DQTExMB4XDTIzMDcxMDA4MDIyN1oXDTI2MDQwNTA4MDIyN1owgYExCzAJBgNVBAYTAmNuMR8wHQYDVQQKDBZDRkNBIENTIFRFU1QgU00yIE9DQTExMQ4wDAYDVQQLDAVDTkFQUzEZMBcGA1UECwwQT3JnYW5pemF0aW9uYWwtMTEmMCQGA1UEAwwdMDUxQDMxMDIxMDAwODg4OThAeGxAMDAwMDAwMDEwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAASSIGceUTcELVdBO6F0xd4LWSvG2KfDeJJDeVFT0GxKyZ+CwJqLZCVX9V7rH3OGim34olp7QFPHjFj16UQCj7Doo4H1MIHyMB8GA1UdIwQYMBaAFL6mfk09fI+gVebBLwkuLCBDs0J/MEgGA1UdIARBMD8wPQYIYIEchu8qAQIwMTAvBggrBgEFBQcCARYjaHR0cDovL3d3dy5jZmNhLmNvbS5jbi91cy91cy0xNS5odG0wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovLzIxMC43NC40Mi4zL09DQTExL1NNMi9jcmwyODI4MC5jcmwwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSdAfIokLVhVjYzOE8B1JmupwFeTDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDAYIKoEcz1UBg3UFAANIADBFAiAgtrRZ4HENDv11/yNFhSOdSrRrmvHuyVahXH8+aVZQrAIhAM6NTl1CFVewOOVB3VbPuVtYs5dyNpLSqC1tmxj5QtWd";
// String cert = convertToPem( Base64.getDecoder().decode(s));
// System.out.println("------------------------------------------------------------------------------------");
// String dn = api.importCertAndGetDN(cert);
// System.out.println("导入证书成功,dn:" + dn);
System.out.println("------------------------------------------------------------------------------------");
String cert1 = api.getCertByDn(SM2dn,0);
System.out.println("查询证书:" + cert1);
System.out.println("------------------------------------------------------------------------------------");
// boolean delFlag = api.deleteCert(dn);
// System.out.println("删除证书:"+ delFlag);
// System.out.println("------------------------------------------------------------------------------------");
// try {
// String cert2 = api.getCertByDn(dn,0);
// System.out.println("删除后查询证书:" + cert1);
// } catch (Exception e) {
// System.out.println("查询证书失败,证书不存在");
// }
}
@Test
public void testAll() {
//国密证书
String cert = "-----BEGIN CERTIFICATE-----\n" + String cert = "-----BEGIN CERTIFICATE-----\n" +
"MIICMDCCAdagAwIBAgIJAOWoGwJCnjlLMAoGCCqBHM9VAYN1MGcxCzAJBgNVBAYT\n" + "MIICMDCCAdagAwIBAgIJAOWoGwJCnjlLMAoGCCqBHM9VAYN1MGcxCzAJBgNVBAYT\n" +
"AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdIYWlEaWFuMRMwEQYDVQQK\n" + "AkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAwDgYDVQQHDAdIYWlEaWFuMRMwEQYDVQQK\n" +
@@ -295,73 +458,141 @@ public class Test4NongxinCW {
"BggqgRzPVQGDdQNIADBFAiEA4kgTdn/iA/XYfjTEeOcELwBXd0tTFghkpfP8DhBF\n" + "BggqgRzPVQGDdQNIADBFAiEA4kgTdn/iA/XYfjTEeOcELwBXd0tTFghkpfP8DhBF\n" +
"KFQCIAXZTL6VPtW67tM/DF4ZgFt5S/YIiFombKa2bWOfL81u\n" + "KFQCIAXZTL6VPtW67tM/DF4ZgFt5S/YIiFombKa2bWOfL81u\n" +
"-----END CERTIFICATE-----"; "-----END CERTIFICATE-----";
String cert1 = "-----BEGIN CERTIFICATE-----\n" +
"MIIDNTCCAh2gAwIBAgIFE2lVIzcwDQYJKoZIhvcNAQEFBQAwITELMAkGA1UEBhMC\n" +
"Q04xEjAQBgNVBAoTCUNGQ0EgT0NBMTAeFw0yMjA0MjIwODIyMTVaFw0yNzA0MjIw\n" +
"ODIyMTVaMGQxCzAJBgNVBAYTAkNOMRIwEAYDVQQKEwlDRkNBIE9DQTExDzANBgNV\n" +
"BAsTBlRQQy1TMzEVMBMGA1UECxMMSW5kaXZpZHVhbC0xMRkwFwYDVQQDExBBUkNV\n" +
"NTIwMDAyNTI3MDg1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC74cciiBbs\n" +
"UcfmBxVlMWtsILsc85erRngknMaMW6wFyBsfJGrcL0TC7EO5XIsJXRrJN32vWdoo\n" +
"6Qm8WUGour+hrSNDzJ7cVtNA1ragPIjlkmMgbDLD0UsEbjHmA902079Fktv35L4l\n" +
"Hqe/vBygXcUoWJsGY5+8ykmI8W0LYPRkVwIDAQABo4G0MIGxMB8GA1UdIwQYMBaA\n" +
"FNHb6YiC5d0aj0yqAIy+fPKrG/bZMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9j\n" +
"cmwuY2ZjYS5jb20uY24vUlNBL2NybDMwMDgyLmNybDALBgNVHQ8EBAMCA+gwHQYD\n" +
"VR0OBBYEFMM/joQIWvRFdLOx0HarTXAtZk7RMCgGA1UdJQQhMB8GCCsGAQUFBwMC\n" +
"BggrBgEFBQcDBAYJKoZIhvcvAQEFMA0GCSqGSIb3DQEBBQUAA4IBAQANEhHR34gg\n" +
"iivRj9VTO2lS0StsHQy4A4seq9YmaQa6QZDUEndFwcxr5DN6CAf6xA1YiHG5FoYd\n" +
"yH4sLORUhdfzQUWle7ZTPn4TfFjddPh3RDHXMXOh+pHNgrSjXpdACwadHedJO5e4\n" +
"HqXI8wEoNovDA8HT4ucMmsZHbIyQMhxW9k+DgTHx8nvltqv3reoDou3ekQ1tSWvW\n" +
"nUteKp64vop1ktgiIKjLshKRaUmZO4/fo9EcJHCH51J6f/2TAM7S+IaFzXR/VWf3\n" +
"JaiaGbT8kAJI854SmKWqRE8HVzMo/NYNdP0M7xZ2kt68PVE/UIl20xWii9P2/7Oh\n" +
"KYAnLX1nKjbg\n" +
"-----END CERTIFICATE-----";
List<String> masterNodes = new ArrayList<>(); List<String> masterNodes = new ArrayList<>();
// masterNodes.add("172.16.18.99:8889");
// masterNodes.add("172.16.18.5:8889");
masterNodes.add("172.1.41.139:8889");
masterNodes.add("172.1.41.96:8889"); masterNodes.add("172.1.41.96:8889");
// masterNodes.add("172.16.18.8:8889"); masterNodes.add("172.1.41.139:8889");
int timeout = 1; int timeout = 100;
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("snmp.target.ip", "172.1.41.191"); map.put("snmp.target.ip", "172.1.1.191");
map.put("snmp.target.port", "162"); map.put("snmp.target.port", "162");
map.put("enterprise.oid", "1.3.6.1.4.1.9999"); map.put("enterprise.oid", "1.3.6.1.4.1.9999");
map.put("snmp.community", "public"); map.put("snmp.community", "public");
map.put("snmp.version", "1"); map.put("snmp.version", "1");
String snmpConfig = new Gson().toJson(map); String snmpConfig = new Gson().toJson(map);
//导入证书并获取DN
SydApi4j sydApi4j = new SydApi4j(); SydApi4j sydApi4j = new SydApi4j();
sydApi4j.importCertToServers(masterNodes, timeout, cert1, "12345678", snmpConfig);
stopWatch.stop(); ImportResult importResult = sydApi4j.importCertToServers(masterNodes, timeout, cert, "12345678", snmpConfig);
System.out.println(stopWatch.getTotalTimeSeconds()); System.out.println("导入结果ImportResult:" + new Gson().toJson(importResult));
System.out.println("------------------------------------------------------------------------------------");
String SM2dn = importResult.getCertDn();
System.out.println("导入证书主题为:"+ SM2dn);
//主备模式设置
SydApi4j.SYD_Set_Parameter_HA("172.1.41.139", "172.1.41.139", 8889, 1000);
SydApi4j api = (SydApi4j) new SydApi4j();
//签名原始数据
byte[] orgData = "12345678".getBytes();
//p1裸签名(国密证书)
byte[] nakedSign = api.SYD_NakedSign(orgData, SM2dn);
System.out.println("------------------------------------------------------------------------------------");
System.out.println("p1签名:"+ Util.bytes2HexString(nakedSign));
System.out.println("p1签名2:"+ Util.encodeBase64(nakedSign));
//p1裸签验签(国密证书)
String si = "MEUCIQCp26t1r3lAWrSSM6NmvqfJKlOFgdPyVKzK6FyImDnzYAIgXJV8GUztPGk0YxYGNU5OMoIqnFJRyLGh72hkUjfWDaM=";
boolean ver = api.SYD_NakedVerify(orgData, Util.decodeBase64(si), SM2dn);
System.out.println("------------------------------------------------------------------------------------");
System.out.println("p1验签:"+ ver);
//p7 detach签名(带公钥证书)
String detachedSign = api.detachedSign(orgData, SM2dn);
System.out.println("------------------------------------------------------------------------------------");
System.out.println("p7 detach签名:"+ detachedSign);
//p7 detach验签(带公钥证书)
boolean ver1 = api.detachedVerify(orgData, detachedSign);
System.out.println("------------------------------------------------------------------------------------");
System.out.println("p7 detach验签:"+ ver1);
//从p7签名数据中获取证书,签名数据为base64编码格式
String cert1 = api.getCertBySign(detachedSign);
System.out.println("------------------------------------------------------------------------------------");
System.out.println("根据p7签名值获取的证书为:" + cert1);
//数字信封
// RetWrap genSM2 = api.generateDEByDn(SM2dn, orgData);
// byte[] cipherKey = (byte[]) genSM2.get(SydApi.RET_CIPHER_KEY);
// System.out.println("SM2数字信封: " + new String(cipherKey));
// RetWrap denSM2 = api.decryptDEByDN( SM2dn, cipherKey);
// byte[] oData = (byte[]) denSM2.get("oData");
// System.out.println("SM2信封解密:"+Util.bytes2HexString(oData));
//根据证书DN从加密码机删除证书
// boolean delFlag = api.deleteCert(SM2dn);
// System.out.println("------------------------------------------------------------------------------------");
// System.out.println("删除证书成功:"+ delFlag);
} }
@Test @Test
public void delCert() { public void testDE() {
String SM2dn1 = "C=CN,ST=北京,L=北京,O=信雅达,OU=测试部门1,CN=172.1.41.139"; // SydApi4j sydApi4j = new SydApi4j();
boolean del = api.deleteCert(SM2dn1); //// String SM2dn = "C=CN,ST=北京,L=北京,O=信雅达,CN=172.1.40.188";
System.out.println("删除:"+ del); // String SM2dn = "C=CN,O=China Financial Certification Authority,CN=CFCA ACS TEST SM2 OCA31";
// //数字信封
// RetWrap genSM2 = api.generateDEByDn(SM2dn, orgData);
// byte[] cipherKey = (byte[]) genSM2.get(SydApi.RET_CIPHER_KEY);
// System.out.println("SM2数字信封: " + new String(cipherKey));
// RetWrap denSM2 = api.decryptDEByDN( SM2dn, cipherKey);
// byte[] oData = (byte[]) denSM2.get("oData");
// System.out.println("SM2信封解密:"+Util.bytes2HexString(oData));
String sign = "MEYCIQDo11zaTBYiesXP5Xk2BWHoBI2u+F3W2Kb9DFfDQEntLwIhANzKl8eV3M1cYxrZbsiP2I02HQBQFrkyeUhwW1iVKSt2";
byte[] s1 = Util.decodeBase64(sign);
System.out.println(Util.bytes2HexString(s1));
// String SM2dn = "C=CN,ST=北京,L=北京,O=信雅达,OU=双证,CN=172.1.40.188";
// String ivHex = "31323334353637383132333435363738";
// RetWrap genByDn = api.generateDEByDnICBC(SM2dn, ivHex,orgData,1);
// String cipherKey1 = (String) genByDn.get(SydApi.RET_CIPHER_KEY);
// System.out.println("SM2数字信封: " +cipherKey1);
} }
@Test @Test
public void selectCert() throws Exception { public void verifyCert() throws Exception {
String SM2dn1 = "C=CN,ST=1,L=1,O=1,OU=1,OU=1,CN=1"; String cert1 = "-----BEGIN CERTIFICATE-----\n" +
String s = api.getCertByDn(SM2dn); "MIIDzQYKKoEcz1UGAQQCAqCCA70wggO5AgEBMQ4wDAYIKoEcz1UBgxEFADAMBgoqgRzPVQYBBAIBoIICvjCCArowggJeoAMCAQICBRBXhjVCMAwGCCqBHM9VAYN1BQAwXDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEbMBkGA1UEAwwSQ0ZDQSBURVNUIFNNMiBPQ0ExMB4XDTIzMTAyNjA2MDA1OVoXDTI4MTAyNjA2MDA1OVowcjELMAkGA1UEBhMCY24xFzAVBgNVBAoMDkNGQ0EgVEVTVCBPQ0ExMQ0wCwYDVQQLDARERU1QMRkwFwYDVQQLDBBPcmdhbml6YXRpb25hbC0xMSAwHgYDVQQDDBcwNDFAWkRFTVBAREVNUEAwMDAwMDAwMTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNzTi8Jwrz8XmcUuZVEpfn8aI3WMFdZg+XgxjpD3gE5fPKFtENT7gXdGkNvR5rn0WpmW9gZXy4Y3IEuU7CpV+KqjgfQwgfEwHwYDVR0jBBgwFoAUa/4Y2o9COqa4bbMuiIM6NKLBMOEwSAYDVR0gBEEwPzA9BghggRyG7yoBATAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNuL3VzL3VzLTE0Lmh0bTA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vdWNybC5jZmNhLmNvbS5jbi9TTTIvY3JsNTM4NjMuY3JsMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUhJRis7GSdOETHetLBaoh6cZff54wHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMAwGCCqBHM9VAYN1BQADSAAwRQIhAI5ggiJQzXV8NKkWXu6GK5HpeME6YPvnPwvjCi2z30aYAiBFcqzOvKnrlZmhWeWQN07VF0INUWEI8/+coZf944XUPTGB0zCB0AIBATBlMFwxCzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGzAZBgNVBAMMEkNGQ0EgVEVTVCBTTTIgT0NBMQIFEFeGNUIwDAYIKoEcz1UBgxEFADANBgkqgRzPVQGCLQEFAARHMEUCIAty3HjlED9ti0NkRI1wpCr8oUws93qHwlYMU0X2HnS3AiEAtv2/HiXabruxV9WLYeMNsO58qcMiBAy1CKmM/zMJCHI=\n" +
System.out.println(s); "-----END CERTIFICATE-----";
String message = "sdas发顺丰"; String cert2 =
byte[] gbkBytes = message.getBytes("GBK"); "MIIC3DCCAoCgAwIBAgIFIGiRZIYwDAYIKoEcz1UBg3UFADBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQDDBNDRkNBIFRFU1QgU00yIE9DQTExMB4XDTI0MDgxNTA4MzAxMloXDTI3MDIwMTA4MzAxMlowgZExCzAJBgNVBAYTAmNuMR8wHQYDVQQKDBZDRkNBIENTIFRFU1QgU00yIE9DQTExMQ4wDAYDVQQLDAVDTkFQUzEZMBcGA1UECwwQT3JnYW5pemF0aW9uYWwtMTE2MDQGA1UEAwwtMDUxQFozMTM1ODEwMDMyODRAMzEzNTgxMDAzMjg0Q05BUFMyQDAwMDAwMDAxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEFRjj5zgEwAnsF7hh6RVJfXSdybPBGBlF7gsVOUX5tU7E0YN/eYZk9j1jbOCrBWz611gsr+HkU0OZsFFlQTattKOB9TCB8jAfBgNVHSMEGDAWgBS+pn5NPXyPoFXmwS8JLiwgQ7NCfzBIBgNVHSAEQTA/MD0GCGCBHIbvKgECMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTUuaHRtMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly8yMTAuNzQuNDIuMy9PQ0ExMS9TTTIvY3JsMjkyODkuY3JsMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUDONZoezPmMkCIHifM0KK9y0N8bQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMAwGCCqBHM9VAYN1BQADSAAwRQIhAKesbWSJQXAHBoLvTbtM+CP7eqwfBMQc0nRridvyXOPOAiAp2Zr1Ncren8n2U1XP4tWeYp1YyPBMke0BSlOFunJ0Jg==";
System.out.println("GBK Encoded Bytes: " + Arrays.toString(gbkBytes)); byte[] s = Base64.getDecoder().decode(cert2);
System.out.println(convertToPem(s));
// Decoding back to String X509Certificate certificate = null;
String decodedMessage = new String(gbkBytes, "GBK"); try {
System.out.println("Decoded Message: " + decodedMessage); certificate = CertUtil.convertToX509Cert(cert1);
} catch (Exception e) {
System.out.println("证书格式错误!");
}
} }
@Test @Test
public void selCert() { public void convert() throws Exception {
String sign = "3045022100F2C494D20823AB12D9D4D23FA12C7D856D4993BE122089D86A515F217CF51C0C02207E06F505F4E70893226F7B22B34E6578570E2813CB0CF1A6775A7782C7C45F7B"; //原始证书
String s = api.getCertBySign(sign); String cert =
System.out.println(s); "MIICujCCAl6gAwIBAgIFEFeGNUIwDAYIKoEcz1UBg3UFADBcMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTEwHhcNMjMxMDI2MDYwMDU5WhcNMjgxMDI2MDYwMDU5WjByMQswCQYDVQQGEwJjbjEXMBUGA1UECgwOQ0ZDQSBURVNUIE9DQTExDTALBgNVBAsMBERFTVAxGTAXBgNVBAsMEE9yZ2FuaXphdGlvbmFsLTExIDAeBgNVBAMMFzA0MUBaREVNUEBERU1QQDAwMDAwMDAxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE3NOLwnCvPxeZxS5lUSl+fxojdYwV1mD5eDGOkPeATl88oW0Q1PuBd0aQ29HmufRamZb2BlfLhjcgS5TsKlX4qqOB9DCB8TAfBgNVHSMEGDAWgBRr/hjaj0I6prhtsy6Igzo0osEw4TBIBgNVHSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTQuaHRtMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly91Y3JsLmNmY2EuY29tLmNuL1NNMi9jcmw1Mzg2My5jcmwwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSElGKzsZJ04RMd60sFqiHpxl9/njAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDAYIKoEcz1UBg3UFAANIADBFAiEAjmCCIlDNdXw0qRZe7oYrkel4wTpg++c/C+MKLbPfRpgCIEVyrM68qeuVmaFZ5ZA3TtUXQg1RYQjz/5yhl/3jhdQ9";
byte[] s = Base64.getDecoder().decode(cert);
System.out.println(convertToPem(s));
String ss = "2025071700064382|2025-06-21T15:39:47|102100088898|102100088898|402361018886|402361018886|BEPS|DM00|202507170013|010000|123456789123456789|1|2025071700064387|王二|地址908|6232208340101760984|402361018886|402361018886|CNY0.05|";
byte[] sss = ss.getBytes();
System.out.println(Util.bytes2HexString(sss));
}
public String convertToPem(byte[] derCert) throws Exception {
// 使用Base64编码器(兼容RFC 4648,每行64字符)
StringWriter writer = new StringWriter();
writer.write("-----BEGIN CERTIFICATE-----\n");
// 将DER转换为Base64并分割为每行64字符
String base64Cert = Base64.getMimeEncoder(64, "\n".getBytes()).encodeToString(derCert);
writer.write(base64Cert);
// 如果Base64编码的字符串没有以换行结束,则添加换行
if (!base64Cert.endsWith("\n")) {
writer.write("\n");
}
writer.write("-----END CERTIFICATE-----\n");
return writer.toString();
} }