diff --git a/doc/java接口说明文档.docx b/doc/java接口说明文档.docx index 307f873..e176303 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 ed87360..3aaa93c 100644 --- a/src/main/java/com/sunyard/inf/SydSVApi.java +++ b/src/main/java/com/sunyard/inf/SydSVApi.java @@ -179,6 +179,15 @@ interface SydAttachedSVApi { */ String attachedSign(byte[] orgData, String sCertDN); + /** + * 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7) + * 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。 + * + * @param sign 已签名数据 + * @return true 验签通过 false 验签失败 + */ + boolean attachedVerify(String sign); + /** * 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7) * 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。 @@ -188,7 +197,7 @@ interface SydAttachedSVApi { * 若发送报文返回证书信息标志位为0,则返回已签名数据, * 若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据 */ - X509 attachedVerify(String sign); + X509 attachedVerifyAndGetX509(String sign); } diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java index ea3af6d..70ad057 100644 --- a/src/main/java/racal/sunyard/main/SydApi4j.java +++ b/src/main/java/racal/sunyard/main/SydApi4j.java @@ -9726,6 +9726,46 @@ public class SydApi4j implements SydApi { return ((PacketSection) ret.get("signature")).getString(); } + @Override + public boolean 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", 0); + + // 渲染发送 + 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 false; + } + + return true; + } + /** * 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7) * 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。 @@ -9734,8 +9774,7 @@ public class SydApi4j implements SydApi { * @return * 返回CERT_INFO结构的证书数据 */ - @Override - public X509 attachedVerify(String sign) { + public X509 attachedVerifyAndGetX509(String sign) { Proto8019 proto = new Proto8019(); //pset.getProtocolReqRender("75"); // 填充数据 diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java index 64afa2f..0a27935 100644 --- a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java +++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java @@ -2089,7 +2089,7 @@ public class TestAllMethods { System.out.println(s); } - // todo: 需要测试 + // 测试通过 // 8018 @Test public void testAttachedSignAndVerify() { @@ -2099,8 +2099,8 @@ public class TestAllMethods { 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())); + boolean verify = api.attachedVerify(sign); + System.out.println("验签结果: " + verify); } // 00883030303030303030 diff --git a/src/test/java/com/sunyard/sydapi/test/TestHT.java b/src/test/java/com/sunyard/sydapi/test/TestHT.java new file mode 100644 index 0000000..c6dd81c --- /dev/null +++ b/src/test/java/com/sunyard/sydapi/test/TestHT.java @@ -0,0 +1,114 @@ +package com.sunyard.sydapi.test; + +import com.sunyard.RetWrap; +import com.sunyard.SydApi; +import com.sunyard.cert.X509; +import com.sunyard.proto.Util; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import racal.sunyard.main.SydApi4j; + +/** + * 衡泰例子 + */ +public class TestHT { + + SydApi4j api; + + @Before + public void before() { + // 通过设置debug的属性开启debug,如果不设置则默认不打开 + System.setProperty("com.sunyard.sydapi4j.debug", "true"); + api = (SydApi4j) new SydApi4j().connect("61.164.40.82", 8889, null, 1000); +// api = (SydApi4j) new SydApi4j().connect("192.168.0.66", 8889, null, 1000); + } + + @After + public void after() { + try { + this.api.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + // + // 测试通过 + // 73 + @Test + public void testSM2ConfirmSessionKeyC() { + + String userId = "1111111111111149"; + + String pk = api.SM2GetPublicKeyC(userId, 1); + + RetWrap retWrap = api.SM2GenSessionKey(pk); + printRetWrap(retWrap); + String cipherKey = (String) retWrap.get(SydApi.RET_CIPHER_KEY); + String sessionKey = (String) retWrap.get(SydApi.RET_SESSION_KEY); + String kcv = (String) retWrap.get(SydApi.RET_KCV); + + RetWrap retWrap1 = api.SM2ConfirmSessionKeyC(userId, cipherKey); + printRetWrap(retWrap1); + sessionKey = (String) retWrap1.get(SydApi.RET_SESSION_KEY); + kcv = (String) retWrap1.get(SydApi.RET_KCV); + } + + // 测试通过 + // 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); + + boolean verify = api.attachedVerify(sign); + System.out.println("验签结果: " + verify); + } + + @Test + public void testAttachedSignAndVerifyGetX509() { + String dn = "C=CN,O=Sunyard,OU=8001,CN=8001"; + String orgData = "111111213323143243243"; + String sign = api.attachedSign(orgData.getBytes(), dn); + System.out.println("签名结果: " + sign); + + X509 verify = api.attachedVerifyAndGetX509(sign); + System.out.println("验签结果: " + Util.bytes2HexString(verify.getPubKey())); + } + + + // =============================工具方法============================================== + + public static void printRetWrap(RetWrap rw) { + printRetWrap(rw, false); + } + + /** + * 输出 + * @param rw + */ + public static void printRetWrap(RetWrap rw, boolean flag) { + for (String s : rw.keySet()) { + + Object o = rw.get(s); + if (o instanceof String) { + System.out.println(s + ":" + o); + } else if (o instanceof byte[]) { + if (flag) { + System.out.println(s + ": " + Util.bytes2HexString((byte[]) o)); + } else { + System.out.println(s + ": " + new String((byte[]) o)); + } + } else { + System.out.println(s + ":" + o); + } + } + } + + + +}