diff --git a/DProto/8018.xml b/DProto/8018.xml
index e9cf04e..12f757b 100644
--- a/DProto/8018.xml
+++ b/DProto/8018.xml
@@ -1,7 +1,6 @@
-
8018
@@ -11,7 +10,7 @@
X509证书序号
-
+
数据长度
@@ -20,14 +19,12 @@
-
-
-
-
+
+
- 8006
+ 8019
@@ -71,7 +68,7 @@
-
+
签名的字节长度
@@ -80,14 +77,22 @@
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/DProto/8019.xml b/DProto/8019.xml
index 2f01c74..a613619 100644
--- a/DProto/8019.xml
+++ b/DProto/8019.xml
@@ -1,23 +1,18 @@
-
8019
-
- X509证书序号
-
-
已签名数据长度
-
+
已签名数据
-
+
@@ -31,14 +26,12 @@
-
-
-
-
+
+
- 8007
+ 8020
@@ -82,11 +75,11 @@
-
+
信息长度
-
+
若发送报文返回证书信息标志位为0,则返回已签名数据,
若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据
@@ -94,12 +87,25 @@
-
-
+
\ No newline at end of file
diff --git a/doc/java接口说明文档.docx b/doc/java接口说明文档.docx
index be1c127..307f873 100644
Binary files a/doc/java接口说明文档.docx and b/doc/java接口说明文档.docx differ
diff --git a/src/main/java/com/sunyard/inf/SydSVApi.java b/src/main/java/com/sunyard/inf/SydSVApi.java
index a74c5ec..ed87360 100644
--- a/src/main/java/com/sunyard/inf/SydSVApi.java
+++ b/src/main/java/com/sunyard/inf/SydSVApi.java
@@ -167,6 +167,28 @@ interface SydAttachedSVApi {
byte[] orgData,
String sign
);
+
+ /**
+ * 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
+ * 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制带公钥证书的数字签名(遵循 PKCS#7)。
+ *
+ * @param orgData 待签名数据
+ * @param sCertDN 证书DN
+ * @return
+ * 符合PKCS7标准的签名结果
+ */
+ String attachedSign(byte[] orgData, String sCertDN);
+
+ /**
+ * 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
+ * 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
+ *
+ * @param sign 已签名数据
+ * @return
+ * 若发送报文返回证书信息标志位为0,则返回已签名数据,
+ * 若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据
+ */
+ X509 attachedVerify(String sign);
}
diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java
index e9d5924..ea3af6d 100644
--- a/src/main/java/racal/sunyard/main/SydApi4j.java
+++ b/src/main/java/racal/sunyard/main/SydApi4j.java
@@ -9668,6 +9668,121 @@ public class SydApi4j implements SydApi {
}
+ /**
+ * 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
+ * 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制带公钥证书的数字签名(遵循 PKCS#7)。
+ *
+ * @param orgData 待签名数据
+ * @param sCertDN 证书DN
+ * @return
+ * 符合PKCS7标准的签名结果
+ */
+ @Override
+ public String attachedSign(byte[] orgData, String sCertDN) {
+ Proto8018 proto = new Proto8018(); //pset.getProtocolReqRender("75");
+ byte[] dn = new byte[256];
+ byte[] s = null;
+ try {
+ s = sCertDN.getBytes("GBK");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ System.arraycopy(s, 0, dn, 0, s.length);
+
+ // 填充数据
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ packet.put("data", data);
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("DN", dn);
+ data.put("infoData", orgData);
+
+ // 渲染发送
+ ByteBuffer bb = proto.rend(packet);
+
+ synchronized (this) {
+ // 响应解析
+ bb = syncRead(syncSend(bb));
+ }
+
+ Packet p = proto.parse(bb);
+ Map ret = p.toMap();
+
+ if (
+ !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
+ ) {
+ throw new SydApiException("包序号不匹配", -4);
+ }
+ ret = (Map) ret.get("data");
+ PacketSection error = (PacketSection) ret.get("error");
+ byte[] be = error.getBytes();
+ if ((0 != (be[0] ^ be[1]))) {
+
+ throw new SydApiException(error.getInfo(), error.autoInt());
+ }
+
+ return ((PacketSection) ret.get("signature")).getString();
+ }
+
+ /**
+ * 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
+ * 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
+ *
+ * @param sign 已签名数据
+ * @return
+ * 返回CERT_INFO结构的证书数据
+ */
+ @Override
+ public X509 attachedVerify(String sign) {
+ Proto8019 proto = new Proto8019(); //pset.getProtocolReqRender("75");
+
+ // 填充数据
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ packet.put("data", data);
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+
+ data.put("signData", sign.getBytes());
+ data.put("flag$option", 1);
+
+ // 渲染发送
+ ByteBuffer bb = proto.rend(packet);
+
+ synchronized (this) {
+ // 响应解析
+ bb = syncRead(syncSend(bb));
+ }
+
+ Packet p = proto.parse(bb, packet);
+ Map ret = p.toMap();
+
+ if (
+ !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
+ ) {
+ throw new SydApiException("包序号不匹配", -4);
+ }
+ ret = (Map) ret.get("data");
+ PacketSection error = (PacketSection) ret.get("error");
+ byte[] be = error.getBytes();
+ if ((0 != (be[0] ^ be[1]))) {
+ return null;
+ }
+
+ PacketSection info = (PacketSection) ret.get("info");
+ byte[] pCertInfo = info.getBytes();
+
+ String certInfo = new String(pCertInfo);
+ int index = certInfo.indexOf("-----BEGIN CERTIFICATE-----");
+ certInfo = certInfo.substring(index);
+// System.out.println("证书信息: " + certInfo);
+ X509 x509 = GetX509CertInfo(certInfo);
+ return x509;
+ }
+
+
// ------------------------中移指令接口--------------------------------
/**
diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
index dc0b99b..64afa2f 100644
--- a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
+++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
@@ -30,7 +30,8 @@ public class TestAllMethods {
public void before() {
// 通过设置debug的属性开启debug,如果不设置则默认不打开
System.setProperty("com.sunyard.sydapi4j.debug", "true");
- api = (SydApi4j) new SydApi4j().connect("192.168.0.66", 8889, null, 1000);
+ api = (SydApi4j) new SydApi4j().connect("61.164.40.82", 8889, null, 1000);
+// api = (SydApi4j) new SydApi4j().connect("192.168.0.66", 8889, null, 1000);
// api = (SydApi4j) new SydApi4j().connect("192.168.0.100", 8889, null, 1000);
// api = (SydApi4j) new SydApi4j().connect("192.168.0.99", 8889, null, 1000);
// api = (SydApi4j) new SydApi4j().connect("172.16.17.162", 8889, null, 1000);
@@ -2088,6 +2089,20 @@ public class TestAllMethods {
System.out.println(s);
}
+ // todo: 需要测试
+ // 8018
+ @Test
+ public void testAttachedSignAndVerify() {
+ String dn = "C=CN,O=Sunyard,OU=8001,CN=8001";
+ String orgData = "111111213323143243243";
+ String sign = api.attachedSign(orgData.getBytes(), dn);
+ System.out.println("签名结果: " + sign);
+
+// String sign = "MIICsgYKKoEcz1UGAQQCAqCCAqIwggKeAgEBMQwwCgYIKoEcz1UBgxEwIAYKKoEcz1UGAQQCAaASBBAzMjE0MzEyMzQxMjQzMjE0oIIByTCCAcUwggFooAMCAQICCDyTAAAAAAAlMAwGCCqBHM9VAYN1BQAwJjELMAkGA1UEBhMCQ04xFzAVBgNVBAMMDlN1bnlhcmRTTTJSb290MB4XDTE3MDUxNzAyNTI0NFoXDTIyMDcyNTAyNTI0NFowPTELMAkGA1UEBhMCQ04xEDAOBgNVBAoMB1N1bnlhcmQxDTALBgNVBAsMBDgwMDExDTALBgNVBAMMBDgwMDEwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQ+2joQe3zDXMAFx/vwu05rQ6B+4U42BgPSLsoqYAstD6AwVdQA0SQDAPVGSLhJ0T9QszD/FDUbVkWxNoaCCmW7o2cwZTAOBgNVHQ8BAf8EBAMCAMAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHwYDVR0jBBgwFoAU93/arv8hxtk6eq2g+6z+AqVO1cEwHQYDVR0OBBYEFAMWZaY2AwaQTNiFLpsa0dyCzBZ6MAwGCCqBHM9VAYN1BQADSQAwRgIhAIl2ZHGfln5hedcousARzZ2yeUjUbxSFMmhMmr5t6Q6nAiEAvqYX/KpIcvnPyB/Yiil+oq6DFdVM6P3vDxBhU/8taXExgZswgZgCAQEwMjAmMQswCQYDVQQGEwJDTjEXMBUGA1UEAwwOU3VueWFyZFNNMlJvb3QCCDyTAAAAAAAlMAoGCCqBHM9VAYMRMAsGCSqBHM9VAYItAQRGMEQCIEons2hit2967ciJo3QipM4lJgd1K3QmwOp9O/n8Tl86AiB9V6Z7jQogZFtoIz6kwAI6OQVnjbtJlmO31bZxgYRwKg==";
+ X509 verify = api.attachedVerify(sign);
+ System.out.println("验签结果: " + Util.bytes2HexString(verify.getPubKey()));
+ }
+
// 00883030303030303030
// 3938
// 30313232