添加8018,8019两个指令所对应的接口。

This commit is contained in:
zhoubin 2022-01-05 17:00:47 +08:00
parent c3236d3547
commit f06bb2a10c
6 changed files with 202 additions and 39 deletions

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base"> <packet extend="base">
<req> <req>
<command> <command>
<bin>8018</bin> <bin>8018</bin>
</command> </command>
@ -11,7 +10,7 @@
X509证书序号 X509证书序号
</DN> </DN>
<dataLen len="4" :value="dataLength()" cn="数据长度"> <dataLen len="2" :value="dataLength()" cn="数据长度">
数据长度 数据长度
</dataLen> </dataLen>
@ -20,14 +19,12 @@
</infoData> </infoData>
</data> </data>
</req> </req>
<res>
<res>
<command> <command>
<bin>8006</bin> <bin>8019</bin>
</command> </command>
<data> <data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')"> <error len="2" cn="错误码" format="X" :catch="catchError('%s')">
@ -71,7 +68,7 @@
</options> </options>
</error> </error>
<signatureLen len="2" cn="签名的字节长度"> <signatureLen len="2" format="X" cn="签名的字节长度">
签名的字节长度 签名的字节长度
</signatureLen> </signatureLen>
@ -80,14 +77,22 @@
</signature> </signature>
</data> </data>
</res> </res>
<script>function dataLength(){
return $packet.data.infoData.length;
<script>
<![CDATA[
function dataLength() {
def len = $packet.data.infoData.length;
def data = new byte[2];
data[0] = (byte)(len >> 8 & 0xFF)
data[1] = (byte)(len & 0xFF)
return data;
} }
]]>
function signatureLen() { function signatureLen() {
return Util.a2i( $final.getSection('data').getSection('signatureLen') ) return Util.b2i( $final.getSection('data').getSection('signatureLen') )
} </script> }
</script>
</packet> </packet>

View File

@ -1,23 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base"> <packet extend="base">
<req> <req>
<command> <command>
<bin>8019</bin> <bin>8019</bin>
</command> </command>
<data extend="data"> <data extend="data">
<DN len="256" cn="证书 DN">
X509证书序号
</DN>
<dataLen len="2" :value="dataLength()" cn="数据长度"> <dataLen len="2" :value="dataLength()" cn="数据长度">
已签名数据长度 已签名数据长度
</dataLen> </dataLen>
<infoData cn="已签名数据"> <signData cn="已签名数据">
已签名数据 已签名数据
</infoData> </signData>
<flag len="2" cn="标记"> <flag len="2" cn="标记">
<options> <options>
@ -31,14 +26,12 @@
</flag> </flag>
</data> </data>
</req> </req>
<res>
<res>
<command> <command>
<bin>8007</bin> <bin>8020</bin>
</command> </command>
<data> <data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')"> <error len="2" cn="错误码" format="X" :catch="catchError('%s')">
@ -82,11 +75,11 @@
</options> </options>
</error> </error>
<infoLen len="2" cn="信息长度"> <infoLen len="2" format="X" :if="0 != $packet.data.flag$option" cn="信息长度">
信息长度 信息长度
</infoLen> </infoLen>
<info :len="infoLen()" cn="信息"> <info :len="reInfoLen()" :if="0 != $packet.data.flag$option" cn="信息">
若发送报文返回证书信息标志位为0则返回已签名数据, 若发送报文返回证书信息标志位为0则返回已签名数据,
若发送报文返回证书信息标志位为1则返回CERT_INFO结构的证书数据 若发送报文返回证书信息标志位为1则返回CERT_INFO结构的证书数据
</info> </info>
@ -94,12 +87,25 @@
</data> </data>
</res> </res>
<script>function dataLength(){ <script>
return $packet.data.infoData.length; <![CDATA[
function dataLength() {
def len = $packet.data.signData.length;
def data = new byte[2];
data[0] = (byte)(len >> 8 & 0xFF)
data[1] = (byte)(len & 0xFF)
return data;
} }
function infoLen() { ]]>
return Util.a2i( $final.data.infoLen )
} </script> function reInfoLen() {
if (null == $final.data.infoLen){
return 0;
}
return Util.b2i( $final.getSection('data').getSection('infoLen') )
}
</script>
</packet> </packet>

Binary file not shown.

View File

@ -167,6 +167,28 @@ interface SydAttachedSVApi {
byte[] orgData, byte[] orgData,
String sign 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);
} }

View File

@ -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<String, Object> packet = new HashMap<String, Object>();
HashMap<String, Object> data = new HashMap<String, Object>();
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<String, Object> ret = p.toMap();
if (
!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
) {
throw new SydApiException("包序号不匹配", -4);
}
ret = (Map<String, Object>) 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<String, Object> packet = new HashMap<String, Object>();
HashMap<String, Object> data = new HashMap<String, Object>();
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<String, Object> ret = p.toMap();
if (
!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
) {
throw new SydApiException("包序号不匹配", -4);
}
ret = (Map<String, Object>) 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;
}
// ------------------------中移指令接口-------------------------------- // ------------------------中移指令接口--------------------------------
/** /**

View File

@ -30,7 +30,8 @@ public class TestAllMethods {
public void before() { public void before() {
// 通过设置debug的属性开启debug如果不设置则默认不打开 // 通过设置debug的属性开启debug如果不设置则默认不打开
System.setProperty("com.sunyard.sydapi4j.debug", "true"); 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.100", 8889, null, 1000);
// api = (SydApi4j) new SydApi4j().connect("192.168.0.99", 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); // api = (SydApi4j) new SydApi4j().connect("172.16.17.162", 8889, null, 1000);
@ -2088,6 +2089,20 @@ public class TestAllMethods {
System.out.println(s); 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 // 00883030303030303030
// 3938 // 3938
// 30313232 // 30313232