diff --git a/doc/java接口说明文档.docx b/doc/java接口说明文档.docx index 6ee337c..66c149f 100644 Binary files a/doc/java接口说明文档.docx and b/doc/java接口说明文档.docx differ diff --git a/src/test/java/com/sunyard/sydapi/sample/TestXJMain.java b/src/test/java/com/sunyard/sydapi/sample/TestXJMain.java new file mode 100644 index 0000000..38fa0a5 --- /dev/null +++ b/src/test/java/com/sunyard/sydapi/sample/TestXJMain.java @@ -0,0 +1,614 @@ +package com.sunyard.sydapi.sample; + +import com.sunyard.RetWrap; +import com.sunyard.SydApi; +import com.sunyard.cert.X509; +import com.sunyard.proto.Util; +import racal.sunyard.main.SydApi4j; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Scanner; + +/** + * 前置模拟服务 + */ +public class TestXJMain { + + public static void main(String[] args) { + String[] inputStrs; + + System.out.println("SydApi 测试程序启动"); + System.setProperty("com.sunyard.sydapi4j.debug", "true"); + SydApi4j api = null; + Scanner sc = new Scanner(System.in); + + api = apiCon(sc); + + if (api != null) { + System.out.println("连接成功"); + } + + while (true) { + + while (api == null) { + api = apiCon(sc); + } + + System.out.print("请输入指令(指令0可以查询所有指令):"); + int code = sc.nextInt(); + // 接int后面的一个换行 + String s = sc.nextLine(); + + try { + + switch (code) { + case 0: // 查询指令 + System.out.println("指令 0: 查询指令\n" + + "指令 1: 更换ip\n" + + "指令 2: PKCS#1签名验签(DN获取公私钥)\n" + + "指令 3: PKCS1签名验签(序列号获取公私钥)\n" + + "指令 4: PKCS#1签名验签(序列号获取公私钥,银联)\n" + + "指令 5: PKCS#1签名验签(ID获取私钥,外部传入公钥,自定义ID)\n" + + "指令 6: PKCS#7签名验签(DN获取私钥)\n" + + "指令 7: PKCS#7签名验签(DN获取私钥, 数据不限长)\n" + + "指令 8: PKCS#7签名(DN获取私钥)\n" + + "指令 9: 生成会话密钥并确认\n" + + "指令 10: 对称密钥加解密-ECB\n" + + "指令 11: 对称密钥加解密-CBC\n" + + "指令 12: 生成数字信封及解密数字信封(网联)\n" + + "指令 13: 通过DN获取公钥\n" + + "指令 14: 通过DN获取序列号\n" + + "指令 15: 通过DN获取公钥\n" + + "指令 16: 通过ID获取公钥\n" + + "指令 17: 通过ID获取X509证书并解析\n" + + "指令 18: 生成SM2密钥对\n" + + "指令 19: 生成SM2密钥对\n" + + "指令 20: SM2加解密\n" + + "指令 21: SM3哈希(带公钥)\n" + + "指令 22: SM3哈希\n" + + "指令 -1: 退出"); + break; + case 1: // 更换ip + apiDisCon(api); + + api = apiCon(sc); + + break; + + case 2: // PKCS#1签名验签(DN获取公私钥) + inputStrs = inputUtil(sc, "DN", "签名验签原数据"); + + testSYD_NakedVerify(api, inputStrs[0], inputStrs[1]); + break; + + case 3: // PKCS1签名验签(序列号获取公私钥) + inputStrs = inputUtil(sc, "序列号", "签名验签原数据"); + + testNetVerify(api, inputStrs[0], inputStrs[1]); + break; + + case 4: // PKCS#1签名验签(序列号获取公私钥,银联) + inputStrs = inputUtil(sc, "序列号", "签名验签原数据"); + + testSM2VerifyCustomized(api, inputStrs[0], inputStrs[1]); + break; + + case 5: // PKCS#1签名验签(ID获取私钥,外部传入公钥,自定义ID) + inputStrs = inputUtil(sc, + "使用者的 ID(生成实体时的机构号)", "id(用于计算SM3-HASH)", "原始数据"); + + testSM2Verify(api, inputStrs[0], inputStrs[1], + inputStrs[2]); + break; + case 6: // PKCS#7签名验签(DN获取私钥) + inputStrs = inputUtil(sc, "签名者证书 DN", "待签名的原始数据"); + + testSYD_DetachedVerify(api, inputStrs[0], inputStrs[1]); + break; + + case 7: // PKCS#7签名验签(DN获取私钥, 数据不限长) + inputStrs = inputUtil(sc, "sm3 hash所用的公钥", + "待签名的原始数据", "签名者证书 DN"); + + testSm3AndDetachedSign(api, inputStrs[0], + inputStrs[1], inputStrs[2]); + break; + + case 8: // PKCS#7签名(DN获取私钥) + inputStrs = inputUtil(sc, "sm3 hash所用的公钥", + "待签名的原始数据", "签名者证书 DN"); + + testDetachedSign(api, inputStrs[0], + inputStrs[1], inputStrs[2]); + break; + + case 9: // 生成会话密钥并确认 + inputStrs = inputUtil(sc, "公钥的der编码", "使用者的ID"); + + testSM2ConfirmSessionKeyC(api, inputStrs[0], inputStrs[1]); + break; + + case 10: // 对称密钥加解密-ECB + inputStrs = inputUtil(sc, "算法标识(0:3DES,1:SM4)", + "使用者的 ID(生成密钥时的机构号)", "加解密原始数据"); + + testSYMEncryptData(api, Integer.parseInt(inputStrs[0]), + inputStrs[1], inputStrs[2]); + break; + case 11: // 对称密钥加解密-CBC + inputStrs = inputUtil(sc, "算法标识(0:3DES,1:SM4)", + "使用者的 ID(生成密钥时的机构号)", "加解密原始数据"); + + testEncDecData(api, Integer.parseInt(inputStrs[0]), + inputStrs[1], inputStrs[2]); + break; + + case 12: // 生成数字信封及解密数字信封(网联) + inputStrs = inputUtil(sc, "X509证书的序列号"); + + testDecryptDE(api, inputStrs[0]); + break; + + case 13: // 通过DN获取公钥 + inputStrs = inputUtil(sc, "证书的DN", "密钥类型(0:签名公钥,1:加密公钥)"); + + testSYD_SM2_Get_Dn_PublicKey_HA(api, inputStrs[0], + Integer.parseInt(inputStrs[1])); + break; + + case 14: // 通过DN获取序列号 + inputStrs = inputUtil(sc, "证书的DN", "证书类型(0:签名证书,1:加密证书)"); + + testGetX509SN(api, inputStrs[0], + Integer.parseInt(inputStrs[1])); + break; + + case 15: // 通过DN获取公钥 + inputStrs = inputUtil(sc, "证书的DN", "证书类型(0:签名证书,1:加密证书)"); + + testGetDNPublicKey(api, inputStrs[0], + Integer.parseInt(inputStrs[1])); + break; + + case 16: // 通过ID获取公钥 + inputStrs = inputUtil(sc, "使用者的ID", "密钥类型(0:签名公钥, 1:加密公钥)"); + + testSM2GetPublicKeyC(api, inputStrs[0], + Integer.parseInt(inputStrs[1])); + break; + case 17: // 通过ID获取X509证书并解析 + inputStrs = inputUtil(sc, "使用者的ID", "证书类型(0:签名证书,1:加密证书)"); + + testGetX509CertFileC(api, inputStrs[0], + Integer.parseInt(inputStrs[1])); + break; + + case 18: // 生成SM2密钥对 + testSM2GenKeyPair(api); + break; + + case 19: // 生成SM2密钥对 + testSYD_SM2GenKeyPair(api); + break; + + case 20: // SM2加解密 + inputStrs = inputUtil(sc, "使用者的ID(生成密钥时的机构号)", "加解密原始数据"); + + testSM2DecryptC(api, inputStrs[0], inputStrs[1]); + break; + + case 21: // SM3哈希(带公钥) + inputStrs = inputUtil(sc, "公钥", "原始数据"); + + testSM3Hash(api, inputStrs[0], inputStrs[1]); + break; + + case 22: // SM3哈希 + inputStrs = inputUtil(sc, "原始数据"); + + testSM3Hash2(api, inputStrs[0]); + break; + case -1: // 退出 + System.out.print("退出程序"); + apiDisCon(api); + + System.exit(0); + default: + System.out.println("输入指令错误,请重新输入...."); + System.out.println("可以输入指令0查询所有指令...."); + } + } catch (Exception e) { + e.printStackTrace(); + continue; + } + } + } + + public static SydApi4j apiCon(Scanner sc) { + SydApi4j api; + System.out.print("请输入ip地址:"); + String ip = sc.nextLine().trim(); + try { + api = (SydApi4j) new SydApi4j().connect(ip, 8889, null, 10000); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("连接未成功,请重新连接..."); + return null; + } + + return api; + } + + // 断开连接 + public static void apiDisCon(SydApi api) { + try { + api.disconnect(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String[] inputUtil(Scanner sc, String... strs) { + String[] retStrs = new String[strs.length]; + + for (int i = 0; i < strs.length; i++) { + System.out.print("请输入" + strs[i] + ":"); + retStrs[i] = sc.nextLine().trim(); + } + + return retStrs; + } + + + // ========================================================================== + // 对称加解密流程-ECB + public static void testSYMEncryptData(SydApi api, int alg, String userId, String orgData) { + + System.out.println("通过id获取公钥"); + String publicKey = api.SM2GetPublicKeyC(userId, 1); + System.out.println("获取的公钥为: " + publicKey); + + // 生成会话密钥 + System.out.println("生成会话密钥"); + RetWrap retWrap = api.SM2GenSessionKey(publicKey); + printRetWrap(retWrap); + String cipherKey = (String) retWrap.get("CipherKey"); + + // 确认会话密钥 + System.out.println("确认会话密钥"); + RetWrap wrap = api.SM2ConfirmSessionKeyC(userId, cipherKey); + printRetWrap(wrap); + String sessionKey = (String) wrap.get(SydApi.RET_SESSION_KEY); + + // 对称加密 + System.out.println("对称加密"); + byte[] bytes = api.SYMEncryptData(alg, sessionKey, orgData.getBytes()); + + System.out.println("对称解密"); + byte[] bytes1 = api.SYMDecryptData(alg, sessionKey, bytes); + System.out.println("解密结果: " + new String(bytes1)); + } + + // 对称加解密流程-CBC + public static void testEncDecData(SydApi api, int alg, String userId, String orgData) { + + System.out.println("通过id获取公钥"); + String publicKey = api.SM2GetPublicKeyC(userId, 1); + System.out.println("获取的公钥为: " + publicKey); + + System.out.println("生成会话密钥"); + RetWrap retWrap = api.SM2GenSessionKey(publicKey); + printRetWrap(retWrap); + String cipherKey = (String) retWrap.get("CipherKey"); + + System.out.println("确认会话密钥"); + RetWrap wrap = api.SM2ConfirmSessionKeyC(userId, cipherKey); + printRetWrap(wrap); + String sessionKey = (String) wrap.get(SydApi.RET_SESSION_KEY); + + // 对称加密 + System.out.println("对称加密"); + byte[] bytes = api.SYMEncryptDataCBC(alg, sessionKey, orgData.getBytes()); + + System.out.println("对称解密"); + byte[] bytes1 = api.SYMDecryptDataCBC(alg, sessionKey, bytes); + System.out.println("解密结果: " + new String(bytes1)); + } + + // PKCS#1签名验签(DN获取公私钥) + // 测试通过 + // 8004 + public static void testSYD_NakedVerify(SydApi api, String dn, String orgData) { + byte[] bytes = api.SYD_NakedSign(orgData.getBytes(), dn); + String sign = Util.bytes2HexString(bytes); + System.out.println("签名结果: " + sign); + + boolean b = api.SYD_NakedVerify(orgData.getBytes(), bytes, dn); + System.out.println("验签结果: " + b); + } + + // PKCS1签名验签(序列号获取公私钥) + // 测试通过 + // 6D + public static void testNetVerify(SydApi api, String sn, String orgData) { + String sign = api.netSign(sn, orgData.getBytes()); + System.out.println("签名结果: " + sign); + + boolean b = api.netVerify(sn, orgData.getBytes(), sign); + System.out.println("验签结果: " + b); + } + + // PKCS#1签名验签(序列号获取公私钥,银联) + // 测试通过 + // 81 + public static void testSM2VerifyCustomized(SydApi api, String sn, String orgData) { + String sign = api.SM2SignCustomized(sn, orgData.getBytes()); + System.out.println("签名结果: " + sign); + + boolean b = api.SM2VerifyCustomized(sn, orgData.getBytes(), sign); + System.out.println("验签结果: " + b); + } + + // PKCS#1签名验签(ID获取私钥,外部传入公钥,自定义ID) + // 测试通过 + // 75 + public static void testSM2Verify(SydApi api, String userId, + String certNo, String orgData) { + + String publicKey = api.SM2GetPublicKeyC(userId, 0); + System.out.println("获取到的公钥: " + publicKey); + + String sign = api.SM2SignC(userId, certNo, 1, + Util.hexString2Bytes(publicKey), orgData.getBytes()); + System.out.println("签名结果: " + sign); + + boolean b = api.SM2Verify(certNo, 1, + Util.hexString2Bytes(publicKey), orgData.getBytes(), sign); + System.out.println("验签结果: " + b); + } + + // PKCS#7签名验签(DN获取私钥, 数据8K以内) + // 测试通过 + // 8006 + public static void testSYD_DetachedVerify(SydApi api, String DN, + String orgData) { + String sign = api.SYD_DetachedSign(orgData.getBytes(), DN); + System.out.println("签名结果" + sign); + + boolean b = api.SYD_DetachedVerify(orgData.getBytes(), sign); + System.out.println("验签结果:" + b); + } + + // PKCS#7签名验签(DN获取私钥, 数据不限长) + // 测试通过 + // 8005 + public static void testSm3AndDetachedSign(SydApi api, String publicKey, + String orgData, String sCertDN) { + + String sign = api.sm3AndDetachedSign(orgData.getBytes(), publicKey, sCertDN); + System.out.println("签名结果: " + sign); + + boolean b = api.sm3AndDetachedVerify(orgData.getBytes(), publicKey, sign); + System.out.println("验签结果:" + b); + } + + // PKCS#7签名(DN获取私钥) + // 测试通过 + // 8005 + public static void testDetachedSign(SydApi api, String publicKey, + String orgData, String sCertDN) { + + byte[] hash = api.SM3Hash(publicKey, orgData.getBytes()); + + String sign = api.detachedSign( + SydApi.DATA_HASH, + hash, + sCertDN + ); + + System.out.println("签名结果: " + sign); + + boolean verify = api.detachedVerify( + SydApi.DATA_HASH, + hash, + sign + ); + + System.out.println("验签结果: " + verify); + } + + // 生成会话密钥并确认 + // 测试通过 + // 73 + public static void testSM2ConfirmSessionKeyC(SydApi api, + String publicKey, + String userId) { + + RetWrap retWrap = api.SM2GenSessionKey(publicKey); + printRetWrap(retWrap); + String cipherKey = (String) retWrap.get("CipherKey"); + + RetWrap retWrap1 = api.SM2ConfirmSessionKeyC(userId, cipherKey); + printRetWrap(retWrap1); + } + + // 生成数字信封及解密数字信封(网联) + // 测试通过 + // 6B + public static void testDecryptDE(SydApi api, String sn) { + + RetWrap retWrap = api.generateDE(sn, (byte) 0x30); + printRetWrap(retWrap); + String CipherKey = (String) retWrap.get("CipherKey"); + + RetWrap retWrap1 = api.decryptDE(sn, CipherKey); + printRetWrap(retWrap1); + } + + // 通过DN获取公钥 + // 测试通过 + // 7E + public static void testSYD_SM2_Get_Dn_PublicKey_HA(SydApi api, + String dn, + int keyType) { + String s = api.SYD_SM2_Get_Dn_PublicKey_HA(dn.getBytes(), keyType); + System.out.println("公钥为: " + s); + } + + // 通过DN获取序列号 + // 测试通过 + // 6E + public static void testGetX509SN(SydApi api, String dn, int keyType) { + String s = api.getX509SN(keyType, dn.getBytes()); + System.out.println("证书序列号: " + s); + } + + // 通过DN获取公钥 + // 测试通过 + // 7E + public static void testGetDNPublicKey(SydApi api, String dn, int keyType) { + String s = api.GetDNPublicKey(keyType, dn.getBytes()); + System.out.println("公钥为: " + s); + } + + // 通过ID获取公钥 + // 测试通过 + // QQ + public static void testSM2GetPublicKeyC(SydApi api, + String userId, + int keyType) { + String s = api.SM2GetPublicKeyC(userId, keyType); + System.out.println("公钥为: " + s); + } + + // 通过ID获取X509证书并解析 + // 测试通过 + // 8017 + public static void testGetX509CertFileC(SydApi api, + String userId, + int keyType) { + String s = api.GetX509CertFileC(userId, keyType); + System.out.println("证书: " + s); + + X509 x509 = api.GetX509CertInfo(s); + System.out.println("证书公钥: " + Util.bytes2HexString(x509.getPubKey())); + } + + // 生成SM2密钥对 + // 测试通过 + // E2 + public static void testSM2GenKeyPair(SydApi api) { + RetWrap retWrap = api.SM2GenKeyPair(); + printRetWrap(retWrap, true); + } + + // 生成SM2密钥对 + // 测试通过 + // QN + public static void testSYD_SM2GenKeyPair(SydApi api) { + RetWrap retWrap = api.SYD_SM2GenKeyPair(); + printRetWrap(retWrap); + } + + // SM2加解密 + // 测试通过 + // 78 + public static void testSM2DecryptC(SydApi api, + String userId, + String orgData) { + + String publicKey = api.SM2GetPublicKeyC(userId, 1); + System.out.println("获取的公钥为: " + publicKey); + + String s = api.SM2Encrypt(Util.hexString2Bytes(publicKey), orgData.getBytes()); + System.out.println("加密结果: " + s); + + byte[] bytes = api.SM2DecryptC(userId, s); + System.out.println("解密结果:" + new String(bytes)); + + } + + // SM3哈希(带公钥) + // 测试通过 + // 76 + // 带公钥 + public static void testSM3Hash(SydApi api, String publicKey, String orgData) { + byte[] hash = api.SM3Hash(publicKey, orgData.getBytes()); + + System.out.println("hash结果:" + Util.bytes2HexString(hash)); + } + + // SM3哈希 + // 测试通过 + // 76 + // 不带公钥 + public static void testSM3Hash2(SydApi api, String orgData) { + byte[] hash = api.SM3Hash(orgData.getBytes()); + + System.out.println("hash结果:" + Util.bytes2HexString(hash)); + } + + // 工具方法 + // ========================================== + + 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(Util.hexString2Bytes(Util.bytes2HexString((byte[]) o)))); + } + } else { + System.out.println(s + ":" + o); + } + } + } + + // 获取证书 + public String getCertStr(String path) { + + BufferedInputStream bis = null; + try { + bis = new BufferedInputStream(new FileInputStream(path)); + + StringBuilder str = new StringBuilder(); + + int len = 0; + + while ((len = bis.read()) != -1) { + str.append((char) len); + } + + return str.toString(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return null; + } + +} diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java index 1d80206..3939db7 100644 --- a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java +++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java @@ -37,11 +37,11 @@ public class TestAllMethods { public void before() { // 通过设置debug的属性开启debug,如果不设置则默认不打开 System.setProperty("com.sunyard.sydapi4j.debug", "true"); - api = (SydApi4j) new SydApi4j().connect("172.16.18.59", 8889, null, 1000); +// api = (SydApi4j) new SydApi4j().connect("172.16.18.59", 8889, null, 1000); // api = (SydApi4j) new SydApi4j().connect("192.168.0.119", 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("172.16.17.162", 8889, null, 1000); // api = (SydApi4j) new SydApi4j().connect("192.168.1.7", 8889, null, 5000); @@ -877,6 +877,7 @@ public class TestAllMethods { System.out.println(check); } + // 从用户存储区获取对称密钥 // 测试通过 // LF @Test