164 Commits
Author SHA1 Message Date
cheney 374ddad9bc Merge remote-tracking branch 'honor3/dev-V2.01' into dev-V2.01
# Conflicts:
#	src/main/java/racal/sunyard/main/SydApi4j.java
2026-06-10 10:32:54 +08:00
cheney ecd2d6cfe1 SM3 性能优化 2026-06-10 10:29:39 +08:00
cheney 55c00b6579 jmeter 测试用例完成 2026-06-10 10:29:38 +08:00
cheney 6cd738a172 jmeter 测试可用 2026-06-10 10:29:37 +08:00
cheney 2c8638a167 jmeter 测试可用 2026-06-10 10:29:36 +08:00
cheney 9c4c19d271 性能简单测试 2026-06-10 10:29:35 +08:00
cheney 17a40377d7 功能测试通过 2026-06-10 10:29:35 +08:00
cheney 18aa757871 性能测试代码 2026-06-10 10:29:34 +08:00
cheney a452376d8d 小于 4M 可以 2026-06-10 10:29:16 +08:00
cheney 7a4a83e6d0 小数据测试通过 2026-06-10 10:27:36 +08:00
cheney b212a265ee byte 转长度 2026-06-10 10:27:16 +08:00
cheney c9a224f810 优化通信 2026-06-10 10:26:44 +08:00
cheney 09f5516792 QN 指令长度错误 2026-06-10 10:26:44 +08:00
cheney 3965146c77 强制指定大端模式 2026-06-10 10:26:21 +08:00
cheney 12b53a2e0f 测试代码整理 2026-06-10 10:25:53 +08:00
cheney 48d9719fbc 测试代码整理 2026-06-10 10:25:53 +08:00
cheney 882e84320c 调整协议,index 改为 4 字节。 2026-06-10 10:25:28 +08:00
cheney 12bdac2d7c 添加测试代码 2026-06-10 10:24:47 +08:00
cheney 31f8c9155e 添加一个性能测试模板 2026-06-10 10:24:46 +08:00
cheney 09a910006f SM3 性能优化 2026-06-10 10:21:15 +08:00
cheney 83e5033ba0 jmeter 测试用例完成 2026-06-09 09:41:10 +08:00
cheney 664bd110c6 jmeter 测试可用 2026-06-08 18:08:10 +08:00
cheney b82002801d jmeter 测试可用 2026-06-08 17:03:46 +08:00
cheney d6a27f3341 性能简单测试 2026-06-08 15:14:22 +08:00
cheney 01be8429be 功能测试通过 2026-06-08 14:08:25 +08:00
陈旻 799f3763d1 6.4警告修复-陈旻 2026-06-04 09:31:50 +08:00
cheney 76809e5521 性能测试代码 2026-06-03 17:23:41 +08:00
cheney 983dc8a47d 小于 4M 可以 2026-06-03 16:34:41 +08:00
cheney 0dc2d7c026 小数据测试通过 2026-06-03 14:08:19 +08:00
cheney 02fd07def2 byte 转长度 2026-06-03 11:44:40 +08:00
cheney 10d9d1b0d6 优化通信 2026-06-02 17:58:02 +08:00
cheney b8322538e7 QN 指令长度错误 2026-06-02 16:26:54 +08:00
cheney 83802b6ef6 强制指定大端模式 2026-06-02 15:06:29 +08:00
cheney 9062a9c17c 测试代码整理 2026-06-01 17:57:23 +08:00
cheney 88f4bdf603 测试代码整理 2026-06-01 13:41:28 +08:00
cheney 385e77b766 调整协议,index 改为 4 字节。 2026-06-01 10:02:49 +08:00
cheney 5259876780 添加测试代码 2026-05-29 18:03:08 +08:00
cheney f7fa777677 添加一个性能测试模板 2026-05-29 17:18:36 +08:00
cheney 1439f4aa63 整理依赖 2026-05-29 17:00:56 +08:00
cheney d1c8201f98 fix 长度问题 2026-05-29 16:44:04 +08:00
cheney 914ba8eee5 添加大数据加密指令 2026-05-29 16:25:04 +08:00
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
waner e2c8695f47 fix:删除证书 2025-06-04 10:32:13 +08:00
waner e4020b1bbc fix:主备切换 2025-06-04 10:13:37 +08:00
waner fbcbe79388 fix:主备切换测试 2025-05-30 16:21:39 +08:00
waner 085d71feb9 fix:jmeter测试 2025-05-23 17:54:00 +08:00
waner 0f46865151 fix:测试demo完善 2025-05-20 17:12:54 +08:00
waner a919287719 fix:测试demo完善 2025-05-20 14:09:45 +08:00
waner 35150c9af4 fix 2025-05-20 14:01:25 +08:00
waner 4616f1b700 测试脚本 2025-05-20 10:30:45 +08:00
waner f8bf4b10fb fix 2025-05-15 13:58:53 +08:00
waner b7cd62a872 fix 2025-05-14 15:02:24 +08:00
waner d3ff2e3646 fix:完善多机证书导入功能 2025-05-14 14:25:34 +08:00
waner 55a9cfbdbe feat:多机证书导入功能 2025-05-08 16:46:30 +08:00
yihzhou db80b1dd83 增加二维码、条形码签名验签测试 2024-11-21 10:56:01 +08:00
yihzhou 25803c9d4f save 2024-07-01 16:10:48 +08:00
yihzhou e866887b3a 完善验证测试程序 2024-06-20 16:09:19 +08:00
yihzhou b37b962dd5 增加验证测试程序 2024-06-17 09:21:28 +08:00
yihzhou f05c04f957 增加证书删除指令 2024-04-11 15:29:30 +08:00
yihzhou 9c2cdb5214 优化E0指令 2023-12-06 15:25:13 +08:00
yihzhou ffd19acbfc 配合网联接口 2023-11-13 15:31:29 +08:00
yihzhou 62598e0c89 完善jmter 2023-11-10 10:03:55 +08:00
yihzhou 9af716e87d 暂存 2023-09-18 10:49:04 +08:00
yihzhou 6f833730c2 本地保存 2023-08-25 15:49:31 +08:00
yihzhou b26aab01a4 保留本地修改至上清分支 2023-08-10 10:45:41 +08:00
yihzhou 7a4f9892f5 保存周一豪电脑 2023-08-02 14:00:36 +08:00
yihzhou ad443356b3 Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing 2023-05-18 16:47:53 +08:00
yihzhou 10622bfb23 p1 p7签名兼容RSA、SM2 2023-05-18 16:45:32 +08:00
cheney e675d8a530 hash 2023-04-17 14:35:01 +08:00
cheney 52e47a5809 整理示例代码 2023-04-17 14:29:04 +08:00
cheney ca32bb4c18 save 2023-02-28 15:20:38 +08:00
cheney 772458254e 添加单元测试 2022-12-16 16:58:31 +08:00
cheney 7d0aebad53 重命名函数 hash 2022-12-16 16:47:27 +08:00
cheney 56eb803514 添加测试 2022-12-16 16:46:06 +08:00
yihzhou 758a4ea116 Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing
# Conflicts:
#	DProto/8003.xml
2022-12-15 17:38:09 +08:00
yihzhou 54e636dd4f 增加大数据裸签功能,完善RSA签名功能接口(修改counthash使用) 2022-12-15 17:26:22 +08:00
cheney 92d6301dcc 扩展 8003 指令 2022-12-15 10:02:41 +08:00
cheney 2419ae656a 忽略日志目录 2022-12-14 15:30:19 +08:00
cheney 35a25e2ca7 更新文档 2022-12-13 18:01:32 +08:00
cheney 4ed943b850 获取所有证书测试 2022-12-13 18:00:09 +08:00
yihzhou 85ef86ee49 增加获取所有证书列表问题 2022-12-13 14:08:24 +08:00
cheney 92ee7a17e8 升级 proto 版本 2022-12-13 11:04:52 +08:00
yihzhou 3f6d316d8b 增加配置项开关控制dn反序 2022-12-09 10:57:32 +08:00
yihzhou 0f28395ce9 完善异常信息捕获、证书列表获取 2022-11-28 10:17:52 +08:00
yihzhou 99a7462fdf Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing 2022-11-10 15:54:40 +08:00
yihzhou d167339d72 SydAttachedSVApi修复 2022-11-10 15:53:47 +08:00
chuzhenyang 8fa39ff4fe Merge remote-tracking branch 'origin/branch' into dev-shangqing
# Conflicts:
#	src/main/java/racal/sunyard/main/SydApi4j.java
2022-11-10 15:51:45 +08:00
chuzhenyang d0fbe3e48c 获取证书列表测试 2022-11-10 15:47:29 +08:00
chuzhenyang 25af2e8fde 移除目标文件 2022-11-10 15:46:21 +08:00
yihzhou 9ab25d4899 修正SydAttachedSVApi 2022-11-08 17:36:45 +08:00
yihzhou 9fd5d5dc8e Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing 2022-11-08 17:12:56 +08:00
yihzhou f345d47dd2 save 2022-11-08 17:12:14 +08:00
yihzhou ecd01a408e save 2022-11-08 17:12:05 +08:00
cheney 06e29e8821 开放接口 2022-11-04 18:27:51 +08:00
cheney 3941c3bf33 开放 pool 参数 2022-11-04 17:44:56 +08:00
chuzhenyang fef31bd7b9 查询所有证书及demo,P1P7性能测试demo 2022-11-03 09:21:27 +08:00
yihzhou fd6ef6050f 完善RSA大数据数字信封 2022-10-28 11:20:22 +08:00
cheney c95130c6ed Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing 2022-10-26 17:44:17 +08:00
cheney fdadf11c93 连接池 2022-10-26 17:44:10 +08:00
yihzhou 952f274f5a Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing 2022-10-26 17:36:02 +08:00
cheney 24161e2ad5 合并
# Conflicts:
#	pom.xml
#	src/main/java/com/sunyard/SydApiException.java
#	src/main/java/racal/sunyard/main/SydApi4j.java
#	src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
2022-10-26 17:24:39 +08:00
cheney d0ea067870 整理日志
# Conflicts:
#	src/main/java/com/sunyard/log/SydLogFactory.java
#	src/main/java/com/sunyard/log/SydLogInfo.java
#	src/main/java/com/sunyard/log/SydLogger.java
#	src/main/java/racal/sunyard/main/SydApi4j.java
2022-10-26 17:19:33 +08:00
yihzhou 2ec20ad3c8 更新依赖 2022-10-26 16:40:18 +08:00
yihzhou 99b5956143 增加及修改文件以适应RSA密钥签名验签功能 2022-10-26 10:05:14 +08:00
cheney d7fe309b08 添加证书类型判断 2022-10-13 15:23:55 +08:00
cheney 01f7ac1f31 证书工具 2022-10-13 10:25:19 +08:00
cheney f36b8c2ca3 证书工具 2022-10-13 10:21:45 +08:00
cheney ee395aebee 证书工具 2022-10-12 16:31:11 +08:00
junj2.liang 48a1aa828c 修改异常类 2022-09-08 10:33:38 +08:00
cheney 1be35ace33 示例代码 2022-09-05 20:50:45 +08:00
cheney 37dd4ea78c fix bugs 2022-09-05 20:35:51 +08:00
cheney 055942f35f fix bugs 2022-09-05 20:35:09 +08:00
chuzhenyang 2cd50187d6 修改异常类 2022-09-05 16:02:14 +08:00
yihzhou 5f424168f7 测试上清所接口 2022-09-05 15:55:50 +08:00
cheney 77dd48f8a0 Merge remote-tracking branch 'gitrep/dev-shangqing' into dev-shangqing-origin
# Conflicts:
#	.gitignore
#	src/main/java/com/sunyard/SydApiException.java
2022-09-05 15:49:46 +08:00
cheney 8ccb1b983e 重命名 2022-09-05 13:54:31 +08:00
yihzhou 7e177e2518 Merge remote-tracking branch 'origin/dev-shangqing' into dev-shangqing 2022-09-05 11:09:04 +08:00
yihzhou bed95d2009 增加签名数字信封、解签名数字信封接口 2022-09-05 11:06:34 +08:00
junj2.liang 1816e26253 修改异常类 2022-08-24 16:51:02 +08:00
cheney f59e25757f 包大小 2022-08-18 20:21:02 +08:00
cheney 44beda611d 打包大小 2022-08-18 20:10:23 +08:00
cheney d8b40a51b5 Detach DN 反转问题 2022-08-18 18:25:22 +08:00
cheney 748571082b Detach DN 反转问题 2022-08-18 17:48:56 +08:00
cheney 0af77f706a 打包 2022-08-18 17:13:24 +08:00
cheney 726eecdbc6 打包 2022-08-18 16:03:43 +08:00
cheney f5ffa53b68 打包 2022-08-18 15:45:15 +08:00
cheney 44b3247d3d 不再提供 maven 2022-08-18 15:41:25 +08:00
cheney 4ddd0d47fd 优化异常 2022-08-18 15:36:12 +08:00
cheney 8ee487fbd0 合并代码 2022-08-18 15:05:35 +08:00
cheney 3b246776aa Merge branch 'dev-icbc' into dev-shangqing
# Conflicts:
#	.gitignore
#	doc/java接口说明文档.docx
#	src/main/java/racal/sunyard/main/SydApi4j.java
#	src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
#	src/test/java/com/sunyard/sydapi/test/TestSV.java
2022-08-18 14:58:18 +08:00
cheney d1dab301d9 忽略目标文件 2022-08-18 14:39:30 +08:00
cheney db067ee91c 修正依赖 2022-08-18 10:29:06 +08:00
cheney 0e398363f4 更新文档 2022-08-18 10:22:17 +08:00
cheney fd0bd53a73 更新打包脚本 2022-08-09 14:39:36 +08:00
cheney f360712042 忽略 pack 2022-08-09 14:38:20 +08:00
cheney 6daefe5d48 添加 SM3 接口变种 2022-07-21 09:47:30 +08:00
cheney dbc5530853 添加 SM3 接口变种 2022-07-21 09:45:17 +08:00
cheney 899b0cc1ca 上清新增接口 2022-07-18 16:32:37 +08:00
cheney 959dd73022 更新上清大数据 P7 接口 2022-07-15 10:50:27 +08:00
cheney a982f8b2df 多线程安全的接口 2022-07-15 10:19:58 +08:00
cheney ba3f91df54 忽略临时文件 2022-07-15 10:19:22 +08:00
cheney 1e84209fea 更新打包命令 2022-07-13 11:31:51 +08:00
cheney 50178ef483 loadrunner 脚本 2022-07-13 11:04:30 +08:00
cheney d9c5e01105 扩展异常类 2022-07-12 09:47:34 +08:00
cheney 6cb3072453 打包签名验签 2022-06-24 11:52:03 +08:00
cheney 0c13d0c38a E0 分包设置为 4064 2022-06-22 20:53:33 +08:00
cheney 8e3e0c5f11 cms decrypt iv
1. 数字信封解封时使用数字信封中的 IV
2. 数字信封解封格式错误时抛出异常 IllegalArgumentException("数字信封解封格式错误")
2022-06-22 17:37:13 +08:00
cheney 6bd2cf1197 Add function "attachedSignC" for customized 2022-06-22 10:07:50 +08:00
cheney b5332438f4 function params type byte[] string 2022-06-22 09:58:51 +08:00
cheney 080c705d72 确认参数 2022-06-21 18:40:51 +08:00
cheney 3cd9e78990 DN reverse bug fix 2022-06-21 18:14:28 +08:00
cheney 15124bf487 DN auto reverse 2022-06-21 17:07:02 +08:00
cheney 9830dea17b 20M 依赖说明 2022-06-21 15:44:41 +08:00
cheney 787be6e294 20M 数字信封支持 2022-06-21 15:39:55 +08:00
cheney 4404f89dd6 p7 证书相关 2022-06-20 16:15:38 +08:00
149 changed files with 21801 additions and 5854 deletions
+4
View File
@@ -11,3 +11,7 @@
/.DS_Store
src/test/java/com/sunyard/sydapi/sample/*.*
*.p7
~$*
/pack/
/.logs/
/bin/
+200 -152
View File
@@ -1,195 +1,233 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<req>
<command>
<hex>6A</hex>
</command>
<data extend="data">
<alg len="1" cn="算法标识">
<options>
<option cn="RSA2048_AES256_ECB">
<hex>0</hex>
</option>
<option cn="SM2_SM4_ECB">
<hex>1</hex>
</option>
<option cn="SM2_SM4_ECB 机构码|02|密钥">
<hex>2</hex>
</option>
<option cn="PKCS7_SM2_SM4_ECB">
<hex>3</hex>
</option>
</options>
</alg>
<command>
<hex>6A</hex>
</command>
<data extend="data">
<alg len="1" cn="算法标识">
<options>
<option cn="RSA2048_AES256_ECB">
<hex>0</hex>
</option>
<option cn="SM2_SM4_ECB">
<hex>1</hex>
</option>
<option cn="SM2_SM4_ECB 机构码|02|密钥">
<hex>2</hex>
</option>
<option cn="PKCS7_SM2_SM4_ECB">
<hex>3</hex>
</option>
<option cn="RSA2048_AES256_CBC">
<hex>4</hex>
</option>
</options>
</alg>
<pFlag len="1" required="false" cn="P标志">
可选,存在,则固定值为‘P’
</pFlag>
<pFlag len="1" required="false" cn="P标志">
可选,存在,则固定值为‘P’
</pFlag>
<certificateModel len="1" cn="证书模式">
<options>
<option cn="证书序号">
<hex>0</hex>
</option>
<option cn="证书 DN">
<hex>1</hex>
</option>
</options>
</certificateModel>
<certificateModel len="1" cn="证书模式">
<options>
<option cn="证书序号">
<hex>0</hex>
</option>
<option cn="证书 DN">
<hex>1</hex>
</option>
</options>
</certificateModel>
<certificateLen len="4" :value="certificateLen()" cn="证书内容长度">
根据证书模式,需要输入内容项的长度 n
</certificateLen>
<certificateLen len="4" :value="certificateLen()" cn="证书内容长度">
根据证书模式,需要输入内容项的长度 n
</certificateLen>
<certificateSn :len="strlen()" :if="0 == $packet.data.certificateModel$option" cn="X509 证书序号">
可选项,只针对“证书模式”为 0时有。
</certificateSn>
<certificateSn :len="strlen()" :if="0 == $packet.data.certificateModel$option" cn="X509 证书序号">
可选项,只针对“证书模式”为 0时有。
</certificateSn>
<certificateDn :len="strlen()" :if="1 == $packet.data.certificateModel$option" cn="X509 证书的 subject">
可选项,只针对“证书模式”为 1时有。
</certificateDn>
<certificateDn :len="strlen()" :if="1 == $packet.data.certificateModel$option" cn="X509 证书的 subject">
可选项,只针对“证书模式”为 1时有。
</certificateDn>
<orgDataLen len="4" :value="dataLen()" :if="3 == $packet.data.alg$option" cn="数据长度">
只针对算法标识为3时传入
</orgDataLen>
<orgDataLen len="4" :value="dataLen()" :if="3 == $packet.data.alg$option||4 == $packet.data.alg$option" cn="数据长度">
只针对算法标识为3、4时传入
</orgDataLen>
<orgData :if="3 == $packet.data.alg$option" cn="数据长度">
只针对算法标识为3时传入
</orgData>
<orgData :if="3 == $packet.data.alg$option||4== $packet.data.alg$option" cn="数据长度">
只针对算法标识为3、4时传入
</orgData>
<keyType len="1" cn="加密密钥方案">
LMK 下加密密钥的方案。
</keyType>
<keyType len="1" cn="加密密钥方案">
LMK 下加密密钥的方案。
</keyType>
<orgCodeLen len="2" :value="orgCodeLen()" :if="hasOrgCode()" cn="机构码长度">
公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
</orgCodeLen>
<orgCodeLen len="2" :value="orgCodeLen()" :if="hasOrgCode()" cn="机构码长度">
公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
</orgCodeLen>
<orgCode :if="hasOrgCode()" cn="机构码长度">
公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
</orgCode>
<orgCode :if="hasOrgCode()" cn="机构码长度">
公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
</orgCode>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X’19”。
<hex>19</hex>
</tailSep>
<!-- 新增功能-->
<pSignFlag len="1" required="false" cn="可选字段">
签名数字信封标识符,存在则为P
</pSignFlag>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
<signCertificateLen len="4" :value="signCertificateLen()" :if="hasOrgCN()" cn="签名证书DN长度">
可选项,只针对"可选字段"为P时存在。
</signCertificateLen>
</req>
<signCertificateDn :len="strlen()" :if="hasOrgCN()" cn="签名证书DN">
可选项,只针对“证书模式”为1时有,只针对"可选字段"为P时存在。
</signCertificateDn>
<signCertificateModel len="1" :if="hasOrgCN()" cn="是否附带公钥信息">
<options>
<option cn="无需附带">
<hex>0</hex>
</option>
<option cn="附带公钥信息">
<hex>1</hex>
</option>
</options>
</signCertificateModel>
<res>
<command>
<hex>6B</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="公钥不符合编码规则">
<hex>04</hex>
</option>
<option cn="无效的加密标识">
<hex>06</hex>
</option>
<option cn="无效的附加模式标识">
<hex>07</hex>
</option>
<option cn="密钥奇偶校验错误">
<hex>10</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="密钥块长度错误">
<hex>76</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X’19”。
<hex>19</hex>
</tailSep>
<keyLen len="4" cn="密钥密文长度">
公钥加密的密钥密文长度
</keyLen>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
<key :len="getKeyLen()" cn="密钥密文">
公钥加密的密钥密文的 BASE64 编码
</key>
</req>
<lmkHead len="1" cn="lmk 头">
如果是 'L' ,lmk 32 个字节长,否则 lmk 64 个字节长。
</lmkHead>
<lmk :len="lmkLen()" cn="对称密钥的密文">
对称密钥的密文,由 LMK30-31 保护。
</lmk>
<res>
<command>
<hex>6B</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="公钥不符合编码规则">
<hex>04</hex>
</option>
<option cn="无效的加密标识">
<hex>06</hex>
</option>
<option cn="无效的附加模式标识">
<hex>07</hex>
</option>
<option cn="密钥奇偶校验错误">
<hex>10</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="密钥块长度错误">
<hex>76</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<keyCheck len="16" cn="密钥校验值">
密钥校验值
</keyCheck>
<keyLen len="4" cn="密钥密文长度">
公钥加密的密钥密文长度
</keyLen>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。
<hex>19</hex>
</tailSep>
<key :len="getKeyLen()" cn="密钥密文">
公钥加密的密钥密文的 BASE64 编码
</key>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
<lmkHead len="1" cn="lmk 头">
如果是 'L' ,lmk 32 个字节长,否则 lmk 64 个字节长。
</lmkHead>
<lmk :len="lmkLen()" cn="对称密钥的密文">
对称密钥的密文,由 LMK30-31 保护。
</lmk>
<keyCheck len="16" cn="密钥校验值">
密钥校验值
</keyCheck>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
</res>
<script>
function certificateLen(){
var data = $packet.data;
if( 0 == data.certificateModel$option ){
return data.certificateSn.length
}
if( 1 == data.certificateModel$option ){
return data.certificateDn.length
}
var data = $packet.data;
if( 0 == data.certificateModel$option ){
return data.certificateSn.length
}
if( 1 == data.certificateModel$option ){
return data.certificateDn.length
}
}
function signCertificateLen(){
var data = $packet.data;
if( 'P' == $packet.data.pSignFlag ){
return data.signCertificateDn.length
}
return null;
}
function getKeyLen() {
return Util.a2i( $final.getSection('data').getSection('keyLen') )
return Util.a2i( $final.getSection('data').getSection('keyLen') );
}
function lmkLen() {
if( Arrays.equals("L".getBytes(),
$final.getSection('data').getSection('lmkHead').getValue()
) ){
return 64
}else{
return 32
}
if( Arrays.equals("L".getBytes(),
$final.getSection('data').getSection('lmkHead').getValue()
) ){
return 64;
}else{
return 32;
}
}
function dataLen() {
return $packet.data.orgData.length()
return $packet.data.orgData.length
}
<![CDATA[
function hasOrgCode() {
if(2 == $packet.data.alg$option && 'P' == $packet.data.pFlag) {
@@ -199,11 +237,21 @@
return false;
}
function hasOrgCN() {
if(1 == $packet.data.certificateModel$option && 'P' == $packet.data.pSignFlag) {
return true;
}
return false;
}
function orgCodeLen() {
def len = $packet.data.orgCode.length();
def data = new byte[2];
data[0] = (byte)(len >> 8 & 0xFF)
data[1] = (byte)(len & 0xFF)
data[0] = (byte)(len >> 8 & 0xFF);
data[1] = (byte)(len & 0xFF);
return data;
}
+40 -9
View File
@@ -11,6 +11,18 @@
可选,如果输入P代表使用PKCS7_SM2_SM4_ECB模式解密数字信封
</pFlag>
<!--新增-->
<pSignFlag len="1" required="false" if="'P' == $packet.data.pFlag" cn="可选字段2">
如果输入P代表进行解封签名数字信封模式,必须当可选字段1为P时才可选
</pSignFlag>
<signCertificateLen len="4" :value="signCertificateLen()" if="'P' == $packet.data.pSignFlag" cn="签名证书内容长度">
根据证书模式,需要输入内容项的长度n,只针对可选字段2为P时存在
</signCertificateLen>
<signCertificateDn :if="hasSign()" cn="签名证书DN">
X509证书的subject可选项,只针对“证书模式”为1时有,只针对可选字段2为P时存在
</signCertificateDn>
<certificateModel len="1" cn="证书模式">
<options>
<option cn="证书序号">
@@ -36,14 +48,16 @@
可选项,只针对“证书模式”为 1时有。
</certificateDn>
<keyLen len="4" :value="keyLen()" cn="密钥密文长度">
公钥加密的密钥密文长度
</keyLen>
<key :len="getKeyLen()" cn="密钥密文">
公钥加密的密钥密文的 BASE64 编码
</key>
<keyType len="1" cn="加密密钥方案">
LMK 下加密密钥的方案。
</keyType>
@@ -57,6 +71,8 @@
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
@@ -126,7 +142,7 @@
对称密钥的密文,由 LMK30-31 保护。
</lmk>
<keyCheck len="16" cn="密钥校验值">
<keyCheck len="32" cn="密钥校验值">
密钥校验值
</keyCheck>
@@ -155,15 +171,30 @@
function certificateLen(){
var data = $packet.data;
if( 0 == data.certificateModel$option ){
return data.certificateSn.length()
return data.certificateSn.length
}
if( 1 == data.certificateModel$option ){
return data.certificateDn.length()
return data.certificateDn.length
}
}
function signCertificateLen(){
var data = $packet.data;
return data.signCertificateDn.length
}
<![CDATA[
function hasSign() {
if(1 == $packet.data.certificateModel$option && 'P' == $packet.data.pSignFlag) {
return true;
}
return false;
}
]]>
function keyLen() {
return $packet.data.key.length()
return $packet.data.key.length;
}
@@ -175,17 +206,17 @@
if( Arrays.equals("L".getBytes(),
$final.getSection('data').getSection('lmkHead').getValue()
) ){
return 64
return 64;
}else{
return 32
return 32;
}
}
function orgCodeLen() {
return Util.a2i( $final.getSection('data').getSection('orgCodeLen') )
return Util.a2i( $final.getSection('data').getSection('orgCodeLen') );
}
function oDataLen() {
return Util.a2i( $final.getSection('data').getSection('oDataLen') )
return Util.a2i( $final.getSection('data').getSection('oDataLen') );
}
</script>
</packet>
+191
View File
@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>6B</hex>
</command>
<data extend="data">
<pFlag len="1" required="false" cn="P标志">
可选,如果输入P代表使用PKCS7_SM2_SM4_ECB模式解密数字信封
</pFlag>
<certificateModel len="1" cn="证书模式">
<options>
<option cn="证书序号">
<hex>0</hex>
</option>
<option cn="证书 DN">
<hex>1</hex>
</option>
</options>
</certificateModel>
<certificateLen len="4" :value="certificateLen()" cn="证书内容长度">
根据证书模式,需要输入内容项的长度 n
</certificateLen>
<certificateSn :len="strlen()" :if="0 == $packet.data.certificateModel$option" cn="X509 证书序号">
可选项,只针对“证书模式”为 0时有。
</certificateSn>
<certificateDn :if="1 == $packet.data.certificateModel$option" cn="X509 证书的 subject">
可选项,只针对“证书模式”为 1时有。
</certificateDn>
<keyLen len="4" :value="keyLen()" cn="密钥密文长度">
公钥加密的密钥密文长度
</keyLen>
<key :len="getKeyLen()" cn="密钥密文">
公钥加密的密钥密文的 BASE64 编码
</key>
<keyType len="1" cn="加密密钥方案">
LMK 下加密密钥的方案。
</keyType>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X’19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>6C</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="公钥不符合编码规则">
<hex>04</hex>
</option>
<option cn="无效的加密标识">
<hex>06</hex>
</option>
<option cn="无效的附加模式标识">
<hex>07</hex>
</option>
<option cn="密钥奇偶校验错误">
<hex>10</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="输入的数据格式错误">
<hex>21</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="密钥块长度错误">
<hex>76</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<oDataLen len="4" cn="明文数据长度">
明文原始数据长度(只针对P存在时,无P时为0)
</oDataLen>
<oData :len="oDataLen()" cn="明文数据">
原始数据(只针对P存在时,无P时不存在)
</oData>
<!--<keyLen len="4" cn="密钥密文长度">-->
<!--公钥加密的密钥密文长度-->
<!--</keyLen>-->
<lmkHead len="1" cn="lmk 头">
如果是 'L' ,lmk 32 个字节长,否则 lmk 64 个字节长。
</lmkHead>
<lmk :len="lmkLen()" cn="对称密钥的密文">
对称密钥的密文,由 LMK30-31 保护。
</lmk>
<keyCheck len="16" cn="密钥校验值">
密钥校验值
</keyCheck>
<orgCodeLen len="4" cn="机构码长度">
公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
</orgCodeLen>
<orgCode :len="orgCodeLen()" cn="机构码长度">
公钥加密的密钥格式3所需机构码长度,仅当格式3以及'P'存在时存在
</orgCode>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function certificateLen(){
var data = $packet.data;
if( 0 == data.certificateModel$option ){
return data.certificateSn.length
}
if( 1 == data.certificateModel$option ){
return data.certificateDn.length
}
}
function keyLen() {
return $packet.data.key.length
}
function getKeyLen() {
return Util.a2i( $final.getSection('data').getSection('keyLen') )
}
function lmkLen() {
if( Arrays.equals("L".getBytes(),
$final.getSection('data').getSection('lmkHead').getValue()
) ){
return 64
}else{
return 32
}
}
function orgCodeLen() {
return Util.a2i( $final.getSection('data').getSection('orgCodeLen') )
}
function oDataLen() {
return Util.a2i( $final.getSection('data').getSection('oDataLen') )
}
</script>
</packet>
+3
View File
@@ -6,6 +6,9 @@
<hex>72</hex>
</command>
<data extend="data">
<pFlag len="1" required="false" cn="RSA标志符">
可选,存在,则固定值为‘R’
</pFlag>
<publicKeyLength len="4" :value="publicKeyLen()" cn="公钥长度">
公钥长度
+12 -1
View File
@@ -75,7 +75,7 @@
</error>
<hash len="32" :if="0 == $packet.data.packSn$option || 3 == $packet.data.packSn$option" cn="hash"></hash>
<hash :len="hashLen()" :if="0 == $packet.data.packSn$option || 3 == $packet.data.packSn$option" cn="hash"></hash>
<filterDataLen len="4" :value="filterDataLength()" :if="2 == $packet.data.packSn$option || 1 == $packet.data.packSn$option" cn="过渡数据长度">
只对“消息块号”为 2、1 时有效
@@ -108,6 +108,17 @@ function filterDataLength(){
var data = $packet.data;
return data.filterData.length;
}
function hashLen(){
if (0 == $packet.data.hashType$option){
return 20;
}
if (1== $packet.data.hashType$option){
return 32;
}
if (2 == $packet.data.hashType$option){
return 16;
}
}
function getFilterDataLen() {
return Util.a2i( $final.getSection('data').getSection('filterDataLen') )
+116 -96
View File
@@ -1,117 +1,137 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<req>
<command>
<bin>8003</bin>
</command>
<data extend="data">
<signatureDataType len="1" cn="获取公私钥标记位">
<options>
<option cn="索引方式">
<bin>00</bin>
</option>
<option cn="DN 方式">
<bin>01</bin>
</option>
</options>
</signatureDataType>
<command>
<bin>8003</bin>
</command>
<data extend="data">
<DN cn="DN 或 DN索引">
若上面的标志为1,则此域为证书DN,若为0,则此域为两个字节的证书索引;
</DN>
<algFlag len="1" :value="algFlag()" cn="算法标记">
</algFlag>
<dataLength len="2" :value="dataLen()" cn="待签名数据长度">
待签名数据长度
</dataLength>
<signatureDataType len="1" cn="获取公私钥标记位">
<options>
<option cn="索引方式">
<bin>00</bin>
</option>
<option cn="DN 方式">
<bin>01</bin>
</option>
</options>
</signatureDataType>
<signData cn="待签名数据">
待签名数据
</signData>
<DN cn="DN 或 DN索引">
若上面的标志为1,则此域为证书DN,若为0,则此域为两个字节的证书索引;
</DN>
</data>
<hashFlag len="1" :if="null != $packet.data.hash" :value="flag()" cn="外部 hash 标记">
</hashFlag>
<hash len="32" :if="null != $packet.data.hash" cn="外部 hash">
</hash>
<dataLength len="2" :value="dataLen()" :if="null == $packet.data.hash" cn="待签名数据长度">
待签名数据长度
</dataLength>
<signData cn="待签名数据" :if="null == $packet.data.hash">
待签名数据
</signData>
</data>
</req>
<res>
</req>
<res>
<command>
<bin>8004</bin>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="无效的私钥类型">
<hex>03</hex>
</option>
<option cn="无效私钥标记">
<hex>04</hex>
</option>
<option cn="无效的哈希标识">
<hex>05</hex>
</option>
<option cn="无效的签名标识">
<hex>06</hex>
</option>
<option cn="无效的附加标识">
<hex>07</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="私钥错误">
私钥错误;报告给管理员。
<hex>49</hex>
</option>
<option cn="无效摘要信息语法(仅仅无哈希模式)">
<hex>74</hex>
</option>
<option cn="公钥长度错误">
<hex>76</hex>
</option>
<option cn="私钥长度错误">
<hex>78</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<command>
<bin>8004</bin>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="无效的私钥类型">
<hex>03</hex>
</option>
<option cn="无效私钥标记">
<hex>04</hex>
</option>
<option cn="无效的哈希标识">
<hex>05</hex>
</option>
<option cn="无效的签名标识">
<hex>06</hex>
</option>
<option cn="无效的附加标识">
<hex>07</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="私钥错误">
私钥错误;报告给管理员。
<hex>49</hex>
</option>
<option cn="无效摘要信息语法(仅仅无哈希模式)">
<hex>74</hex>
</option>
<option cn="公钥长度错误">
<hex>76</hex>
</option>
<option cn="私钥长度错误">
<hex>78</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<signatureLen len="2" cn="签名的字节长度">
签名的字节长度
</signatureLen>
<signatureLen len="2" cn="签名的字节长度">
签名的字节长度
</signatureLen>
<signature :len="signatureLen()" cn="签名的 DER 编码">
签名的 DER 编码
</signature>
<signature :len="signatureLen()" cn="签名的 DER 编码">
签名的 DER 编码
</signature>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。
<hex>19</hex>
</tailSep>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script type="javascript"><![CDATA[
</res>
<script type="javascript"><![CDATA[
function algFlag(){
if( 'P' == $packet.data.rFlag ) {
return ''
} else {
$packet.data.rFlag
}
}
function flag(){
return $packet.data.rFlag;
}
function dataLen(){
def len = $packet.data.signData.length
def ret = new byte[2]
+127 -107
View File
@@ -1,132 +1,152 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<req>
<command>
<bin>8004</bin>
</command>
<data extend="data">
<signatureDataType len="1" cn="获取公私钥标记位">
<options>
<option cn="索引方式">
<bin>00</bin>
</option>
<option cn="DN 方式">
<bin>01</bin>
</option>
<option cn="通过机构号获取">
<bin>02</bin>
</option>
</options>
</signatureDataType>
<command>
<bin>8004</bin>
</command>
<data extend="data">
<DN :if="useDN()" cn="DN 或 DN索引">
若上面的标志为1,则此域为证书DN,若为0,则此域为两个字节的证书索引;若为2,该域不存在
</DN>
<algFlag len="1" :value="algFlag()" cn="算法标记">
</algFlag>
<organizationNumLen len="2" :if="useOrganization()" :value="bNumberLength()" cn="机构号长度">
标志为2 时存在
</organizationNumLen>
<signatureDataType len="1" cn="获取公私钥标记位">
<options>
<option cn="索引方式">
<bin>00</bin>
</option>
<option cn="DN 方式">
<bin>01</bin>
</option>
<option cn="通过机构号获取">
<bin>02</bin>
</option>
</options>
</signatureDataType>
<organizationNum :if="useOrganization()" cn="机构号内容">
标志为2 时存在
</organizationNum>
<DN :if="useDN()" cn="DN 或 DN索引">
若上面的标志为1,则此域为证书DN,若为0,则此域为两个字节的证书索引;若为2,该域不存在
</DN>
<organizationNumLen len="2" :if="useOrganization()" :value="bNumberLength()" cn="机构号长度">
标志为2 时存在
</organizationNumLen>
<dataLength len="2" :value="dataLen()" cn="待签名数据长度">
待签名数据长度
</dataLength>
<organizationNum :if="useOrganization()" cn="机构号内容">
标志为2 时存在
</organizationNum>
<odata cn="待签名数据">
待签名数据
</odata>
<hashFlag len="1" :if="null != $packet.data.hash" :value="flag()" cn="外部 hash 标记">
</hashFlag>
<signatureLen len="2" :value="signLen()" cn="签名的字节长度">
签名的字节长度
</signatureLen>
<hash len="32" :if="null != $packet.data.hash" cn="外部 hash">
</hash>
<signature :len="signatureLen()" cn="已签名数据">
待验签的已签名数据,若为RSA签名则为相应长度的签名数据,若为SM2签名,则前半部分为R.后面半部分为S;
</signature>
<dataLength len="2" :if="null == $packet.data.hash" :value="dataLen()" cn="待签名数据长度">
待签名数据长度
</dataLength>
<returnSign len="2" cn="返回证书信息标志">
<options>
<option cn="不返回">
<bin>0000</bin>
</option>
<option cn="返回">
<bin>0001</bin>
</option>
</options>
</returnSign>
</data>
<odata cn="待签名数据" :if="null == $packet.data.hash">
待签名数据
</odata>
<signatureLen len="2" :value="signLen()" cn="签名的字节长度">
签名的字节长度
</signatureLen>
<signature :len="signatureLen()" cn="已签名数据">
待验签的已签名数据,若为RSA签名则为相应长度的签名数据,若为SM2签名,则前半部分为R.后面半部分为S;
</signature>
<returnSign len="2" cn="返回证书信息标志">
<options>
<option cn="不返回">
<bin>0000</bin>
</option>
<option cn="返回">
<bin>0001</bin>
</option>
</options>
</returnSign>
</data>
</req>
<res>
</req>
<res>
<command>
<bin>8005</bin>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="公钥不符合编码规则">
<hex>04</hex>
</option>
<option cn="无效的加密标识">
<hex>06</hex>
</option>
<option cn="无效的附加模式标识">
<hex>07</hex>
</option>
<option cn="密钥奇偶校验错误">
<hex>10</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="私钥错误">
私钥错误;报告给管理员。
<hex>49</hex>
</option>
<option cn="密钥块长度错误">
<hex>76</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<command>
<bin>8005</bin>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="公钥不符合编码规则">
<hex>04</hex>
</option>
<option cn="无效的加密标识">
<hex>06</hex>
</option>
<option cn="无效的附加模式标识">
<hex>07</hex>
</option>
<option cn="密钥奇偶校验错误">
<hex>10</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="私钥错误">
私钥错误;报告给管理员。
<hex>49</hex>
</option>
<option cn="密钥块长度错误">
<hex>76</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<infoLen len="2" cn="信息长度" :if="0 != $packet.data.returnSign$option">
信息长度
</infoLen>
<infoLen len="2" cn="信息长度" :if="0 != $packet.data.returnSign$option">
信息长度
</infoLen>
<info :len="getInfoLen()" cn="信息" :if="0 != $packet.data.returnSign$option">
若发送报文返回证书信息标志位为0,则返回一段垃圾数据,可以不用管
若发送报文返回证书信息标志位为1,则返回 CERT_INFO 结构的证书数据
</info>
<info :len="getInfoLen()" cn="信息" :if="0 != $packet.data.returnSign$option">
若发送报文返回证书信息标志位为0,则返回一段垃圾数据,可以不用管
若发送报文返回证书信息标志位为1,则返回 CERT_INFO 结构的证书数据
</info>
</data>
</data>
</res>
<script><![CDATA[
function dataLen(){
</res>
<script><![CDATA[
function algFlag(){
if( 'P' == $packet.data.rFlag ) {
return ''
} else {
$packet.data.rFlag
}
}
function flag(){
return $packet.data.rFlag;
}
function dataLen(){
def len = $packet.data.odata.length
def ret = new byte[2]
ret[0] = (byte)(len >> 8 & 0xFF)
+6 -3
View File
@@ -6,6 +6,9 @@
<bin>8005</bin>
</command>
<data extend="data">
<rFlag len="1" required="false" cn="RSA算法标志">
可选,存在,则固定值为‘P’
</rFlag>
<DN len="256" cn="证书 DN">
X509证书序号
@@ -13,13 +16,13 @@
<hashFlag cn="是否为 hash 模式" len="1" required="false"></hashFlag>
<hash cn="hash 值" :if="'P' == $packet.data.hashFlag"></hash>
<hash cn="hash 值" :if="null != $packet.data.hashFlag"></hash>
<dataLen :if="'P' != $packet.data.hashFlag" len="2" format="X" :value="dataLength()" cn="数据长度">
<dataLen :if="null == $packet.data.hashFlag" len="2" format="X" :value="dataLength()" cn="数据长度">
数据长度
</dataLen>
<infoData :if="'P' != $packet.data.hashFlag" cn="数据">
<infoData :if="null == $packet.data.hashFlag" cn="数据">
数据
</infoData>
+6 -4
View File
@@ -6,16 +6,18 @@
<bin>8006</bin>
</command>
<data extend="data">
<rFlag len="1" required="false" cn="RSA算法标志">
可选,存在,则固定值为‘P’
</rFlag>
<hashFlag cn="是否为 hash 模式" len="1" required="false"></hashFlag>
<hash cn="hash 值" :if="'P' == $packet.data.hashFlag"></hash>
<hash cn="hash 值" :if="null != $packet.data.hashFlag"></hash>
<originLen :if="'P' != $packet.data.hashFlag" len="2" :value="orginLength()" cn="待签名数据长度">
<originLen :if=" null == $packet.data.hashFlag" len="2" :value="orginLength()" cn="待签名数据长度">
待签名数据长度
</originLen>
<originData :if="'P' != $packet.data.hashFlag" cn="待签名数据">
<originData :if="null == $packet.data.hashFlag" cn="待签名数据">
待签名数据
</originData>
+4 -16
View File
@@ -7,18 +7,9 @@
</command>
<data extend="data">
<dataFlag len="1" cn="数据包标志">
<options>
<option cn="起始包">
<bin>00</bin>
</option>
<option cn="中间包">
<bin>01</bin>
</option>
<option cn="结束包">
<bin>02</bin>
</option>
</options>
<dataFlag len="4" cn="数据包标志">
0:起始包
其他:传入上一个包返回的数据标志
</dataFlag>
<sqlite3 cn="Sqlite3 查询条件">
@@ -75,10 +66,7 @@
</error>
<dataFlag len="4" cn="数据包标志">
0:起始包
1:中间包
2:结束包
(可能hi因为字节对此,后三字节为垃圾值)
已返回证书个数
</dataFlag>
<certAllNum len="4" cn="证书总数">
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<bin>8011</bin>
</command>
<data extend="data">
<certDn cn="证书dn">
</certDn>
</data>
</req>
<res>
<command>
<bin>8012</bin>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="公钥不符合编码规则">
<hex>04</hex>
</option>
<option cn="无效的加密标识">
<hex>06</hex>
</option>
<option cn="无效的附加模式标识">
<hex>07</hex>
</option>
<option cn="密钥奇偶校验错误">
<hex>10</hex>
</option>
<option cn="LMK 错误">
LMK 错误;报告给管理员。
<hex>13</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="私钥错误">
私钥错误;报告给管理员。
<hex>49</hex>
</option>
<option cn="密钥块长度错误">
<hex>76</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
</data>
</res>
<script> </script>
</packet>
+3
View File
@@ -5,6 +5,9 @@
<bin>8018</bin>
</command>
<data extend="data">
<rFlag len="1" required="false" cn="RSA标志">
可选,存在,则固定值为‘P’
</rFlag>
<DN len="256" cn="证书 DN">
X509证书序号
+66
View File
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>GN</hex>
</command>
<data extend="data">
<Esign len="1" cn="E值">
<text>1</text>
</Esign>
<keyLen len="4" cn="密钥长度">
<text>2048</text>
</keyLen>
<sk len="27" cn="私钥索引"></sk>
<startTime len="8" cn="启用时间"></startTime>
<endTime len="8" cn="到期时间"></endTime>
</data>
</req>
<res>
<command>
<hex>QO</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
<option cn="无效的哈希标识">
<hex>05</hex>
</option>
<option cn="输入数据错">
<hex>15</hex>
</option>
<option cn="DSP 错误">
DSP 错误;报告给管理员。
<hex>47</hex>
</option>
<option cn="输入数据长度错误">
<hex>80</hex>
</option>
</options>
</error>
<pk len="270" cn="公钥"></pk>
<sk len="2824" cn="私钥"></sk>
</data>
</res>
<script> </script>
</packet>
+2 -2
View File
@@ -50,8 +50,8 @@
</options>
</error>
<pk len="32" cn="公钥"></pk>
<sk len="160" cn="私钥"></sk>
<pk len="128" cn="公钥"></pk>
<sk len="64" cn="私钥"></sk>
</data>
+21
View File
@@ -1,3 +1,24 @@
# sydapi4j
加密机 java 接口,基于 jna。
## 启动 Slave
在作为负载机的 Slave 机器上进行配置,主要有两种方式:
方法一:配置 jmeter.properties 文件
编辑 $JMETER_HOME/bin/jmeter.properties 文件,确认或取消注释以下配置:
```
server.rmi.ssl.disable=true # 禁用SSL,简化内网配置
server.rmi.localport=1099 # 固定RMI端口,方便防火墙放行
java.rmi.server.hostname=Slave_IP # 绑定本机网卡IP,避免多网卡问题
```
配置完成后,在 Slave 的 bin 目录下启动服务:
Windows: 双击 jmeter-server.bat
Linux/Mac: 运行 ./jmeter-server
./jmeter-server -Djava.rmi.server.hostname=172.1.41.24 -Dserver.rmi.localport=1099
+30
View File
@@ -0,0 +1,30 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0
http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>assembled-test-jar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!-- 打包主代码 -->
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<!-- 打包测试代码 -->
<fileSet>
<directory>${project.build.testOutputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<!-- 打包依赖的Jar包 -->
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
+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"
}
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+90
View File
@@ -0,0 +1,90 @@
{
"vars": {
"version": "%project.git_branch_version%",
"out_path": "./pack"
},
"clear": [
{
"func": "rm",
"path": "%out_path%"
},
{
"func": "rm",
"path": "./logs"
}
],
"init": [
{
"func": "mkdir",
"path": "%out_path%"
},
{
"func": "mkdir",
"path": "%out_path%/jar"
},
{
"func": "mkdir",
"path": "%out_path%/jar/dependences"
},
{
"func": "mkdir",
"path": "%out_path%/doc"
}
],
"gen" : [{
"cmd" : "dproto"
}],
"build": [
{
"cmd": "clear"
},
{
"cmd": "init"
},
{
"shell": "mvn package -DskipTests",
"check": "BUILD SUCCESS"
},
{
"func": "cp",
"from": "./target/sydapi4j.jar",
"to": "%out_path%/jar/sydapi4j.jar"
},
{
"func": "cp",
"from": "./target/sydapi4j-jar-with-dependencies.jar",
"to": "%out_path%/jar/sydapi4j-jar-with-dependencies.jar"
},
{
"shell" : "mvn dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=%out_path%/jar/dependences",
"check": "BUILD SUCCESS"
},
{
"func": "cp",
"from": "./doc",
"to": "%out_path%/doc"
},
{
"func": "cp",
"from": "./src/test/java/sample",
"to": "%out_path%/sample"
},
{
"func": "cp",
"from": "./˵Ã÷.txt",
"to": "%out_path%/˵Ã÷.txt"
},
{
"func": "zip",
"from": "%out_path%/*",
"to": "%out_path%/sydapi-%version%.%project.git_commit_hash%.zip",
"vc" : "10M"
},
{
"func": "open",
"path": "%out_path%/"
}
]
}
+73 -72
View File
@@ -4,7 +4,7 @@
<groupId>com.sunyard</groupId>
<artifactId>sydapi4j</artifactId>
<version>1.0.20220712</version>
<version>2.01</version>
<packaging>jar</packaging>
<name>sydapi4j</name>
@@ -14,8 +14,8 @@
<vertx>3.4.2</vertx>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
@@ -26,65 +26,78 @@
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.apache.commons</groupId>-->
<!-- <artifactId>commons-pool2</artifactId>-->
<!-- <version>2.11.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.jetbrains.kotlin</groupId>-->
<!-- <artifactId>kotlin-test</artifactId>-->
<!-- <version>${kotlin.version}</version>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/dom4j/dom4j &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>dom4j</groupId>-->
<!-- <artifactId>dom4j</artifactId>-->
<!-- <version>1.6.1</version>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/com.alibaba/fastjson &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>fastjson</artifactId>-->
<!-- <version>1.2.80</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.jetbrains.kotlin</groupId>-->
<!-- <artifactId>kotlin-stdlib-jdk8</artifactId>-->
<!-- <version>${kotlin.version}</version>-->
<!-- </dependency>-->
<!--<dependency>-->
<!--<groupId>com.sunyard</groupId>-->
<!--<artifactId>Converter</artifactId>-->
<!--<version>[1.0.201807251700, 1.1-SNAPSHOT)</version>-->
<!--</dependency>-->
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>junitperf</artifactId>
<version>1.0.3</version>
<scope>test</scope>
</dependency>
<!-- JMeter Java Sampler 核心依赖 -->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.4.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sunyard</groupId>
<artifactId>proto</artifactId>
<version>1.0-20220412</version>
<version>1.1.20221215</version>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.0</version>
</dependency>
<!--<dependency>-->
<!--<groupId>club.fullstack</groupId>-->
<!--<artifactId>serialize</artifactId>-->
<!--<version>[1.0.201806051035, 1.1.SNAPSHOT)</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.wvengen/proguard-maven-plugin -->
<!-- https://mvnrepository.com/artifact/com.github.wvengen/proguard-maven-plugin -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.38</version>
</dependency>
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.8.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.13.1</version>
</dependency>
</dependencies>
<build>
<finalName>sydapi4j</finalName>
@@ -101,6 +114,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<!-- <version>3.8.1</version>-->
<executions>
<execution>
<id>compile</id>
@@ -118,8 +132,8 @@
</execution>
</executions>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>8</source>
<target>8</target>
<compilerId>groovy-eclipse-compiler</compilerId>
<verbose>true</verbose>
<fork>true</fork>
@@ -168,22 +182,6 @@
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.xxx.uploadFile</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
@@ -210,9 +208,12 @@
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>racal.sunyard.main.Version</mainClass>
<mainClass>sample.TestDemo</mainClass>
</manifest>
</archive>
<descriptorRefs>
-31
View File
@@ -1,31 +0,0 @@
// console.log('\x1B[36m%s\x1B[0m', info); //cyan
// console.log('\x1B[33m%s\x1b[0m:', path); //yellow
var styles = {
'bold' : ['\x1B[1m', '\x1B[22m'],
'italic' : ['\x1B[3m', '\x1B[23m'],
'underline' : ['\x1B[4m', '\x1B[24m'],
'inverse' : ['\x1B[7m', '\x1B[27m'],
'strikethrough' : ['\x1B[9m', '\x1B[29m'],
'white' : ['\x1B[37m', '\x1B[39m'],
'grey' : ['\x1B[90m', '\x1B[39m'],
'black' : ['\x1B[30m', '\x1B[39m'],
'blue' : ['\x1B[34m', '\x1B[39m'],
'cyan' : ['\x1B[36m', '\x1B[39m'],
'green' : ['\x1B[32m', '\x1B[39m'],
'magenta' : ['\x1B[35m', '\x1B[39m'],
'red' : ['\x1B[31m', '\x1B[39m'],
'yellow' : ['\x1B[33m', '\x1B[39m'],
'whiteBG' : ['\x1B[47m', '\x1B[49m'],
'greyBG' : ['\x1B[49;5;8m', '\x1B[49m'],
'blackBG' : ['\x1B[40m', '\x1B[49m'],
'blueBG' : ['\x1B[44m', '\x1B[49m'],
'cyanBG' : ['\x1B[46m', '\x1B[49m'],
'greenBG' : ['\x1B[42m', '\x1B[49m'],
'magentaBG' : ['\x1B[45m', '\x1B[49m'],
'redBG' : ['\x1B[41m', '\x1B[49m'],
'yellowBG' : ['\x1B[43m', '\x1B[49m']
};
module.exports = styles
-269
View File
@@ -1,269 +0,0 @@
const l = require("./log")
const os = require("os");
const fs = require('fs');
const path = require('path');
const util = require('util');
const { exec } = require('child_process')
function sync( cmds , options = {}){
if ( options.detached ) {
throw "sync 不支持 detached"
}
options = Object.assign({
// cwd : os.tmpdir(),
encoding: 'buffer'
}, options)
// 支持多命令
let cmd = cmds
// win 乱码问题
let encode = "win32" === os.platform() ? 'cp936' : "utf-8"
return new Promise(function (resolve, reject) {
let process = exec( cmd , options , function (e, stdout, stderr) {
// console.log( e,
// iconv.decode( stdout, 'cp936'),
// iconv.decode( stderr, 'cp936')
// )
if ( e ) {
reject( e )
} else {
resolve( stdout.toString() , stderr.toString() )
// resolve({
// pid : process.pid,
// exitCode : process.exitCode,
// stdout : stdout.toString(),
// stderr : stderr.toString()
// })
}
})
console.log( "process", process.pid )
})
}
var version = ""
const project_path = path.join(__dirname, "../")
const out_path = path.join(project_path, "public")
// 用户文档
const man = "说明.txt"
function prepareDir(){
return new Promise(function (cbok, cberr) {
if ( fs.existsSync( out_path ) ){
l.i("存在旧文件,清空旧文件")
}
sync("rd /s/q .\\public").catch(function (reason) {
// pass
}).finally(function () {
l.i("创建新文件")
fs.mkdirSync( out_path )
fs.mkdirSync( path.join( out_path, "jar" ))
fs.mkdirSync( path.join( out_path, "jar", "dependences"))
// fs.mkdirSync( path.join( out_path, "doc" ))
// fs.mkdirSync( path.join( out_path, "html" ))
// fs.mkdirSync( path.join( out_path, "sample" ))
l.i("目录准备完成")
cbok()
})
})
}
function mvn(){
l.i("调用 maven 打包,可能需要好几分钟。")
return new Promise(function (cbok, cberr) {
sync('mvn package -DskipTests').then(function (value, error) {
if ( error ) {
throw error
}
l.d( value )
if ( value.indexOf("BUILD SUCCESS") < 0 ){
throw new Error("请检查 maven package 命令")
}
// 移动文件到发布目录
fs.renameSync(path.join(project_path, "target", "sydapi4j-jar-with-dependencies.jar")
, path.join(out_path, "jar", "sydapi4j-jar-with-dependencies.jar"))
fs.renameSync(path.join(project_path, "target", "sydapi4j.jar")
, path.join(out_path, "jar", "sydapi4j.jar"))
cbok()
})
})
}
function doc(){
return sync('mvn javadoc:javadoc').then(function (value, error) {
l.d( value )
// if ( value.indexOf("BUILD SUCCESS") < 0 ){
// throw new Error("请检查 maven doc 命令")
// }
}).catch(function (reason) {
l.d("忽略文档生成错误")
})
}
function zipjar(){
return sync("7z a .\\public\\sydapi-"+ version +".zip .\\public\\jar\\").then(function (value, error) {
l.d( value )
if ( value.indexOf("Everything is Ok") < 0 ){
throw new Error("请检查 7z 命令")
}
})
}
function zipsample(){
return sync("7z a .\\public\\sydapi-"+ version +".zip .\\src\\test\\java\\com\\sunyard\\sydapi\\sample").then(function (value, error) {
l.d( value )
if ( value.indexOf("Everything is Ok") < 0 ){
throw new Error("请检查 7z 命令")
}
})
}
function zipdoc(){
return sync("7z a .\\public\\sydapi-"+ version +".zip " + man).then(function (value, error) {
l.d( value )
if ( value.indexOf("Everything is Ok") < 0 ){
throw new Error("请检查 7z 命令")
}
})
}
function dependencies(){
return sync('mvn dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=./public/jar/dependences').then(function (value, error) {
l.d( value )
if ( value.indexOf("BUILD SUCCESS") < 0 ){
throw new Error("请检查 maven dependencies 命令")
}
})
}
async function main() {
l.i("项目目录 : " + project_path )
sync('git status').then(function (value, error) {
l.d( value )
if ( value.indexOf("Command failed") > 0 ){
throw new Error("请检查 git 命令")
}
if ( value.indexOf("Changes not staged for commit") > 0){
throw new Error("项目有文件未保存")
}
if ( value.indexOf("Changes to be committed") > 0 ){
throw new Error("项目有文件未提交")
}
// 匹配分支,获取前两位版本
var r = /^On branch dev-(?<version>\S+)$/gm.exec(value)
l.i( r.groups.version )
version = r.groups.version
return sync('git log -1')
}).then(function (value) {
l.d( value )
var r = /^commit\s(?<id>\S+)$/gm.exec(value)
l.i( r.groups.id )
// 缩短 HASH
var short = r.groups.id.substr(0, 6)
version += "." + short
l.i("目前版本: " + version )
return prepareDir()
}).then(function (value) {
return mvn()
}).then(function (value) {
return dependencies()
}).then(function (value) {
var pom = fs.readFileSync("pom.xml", { encoding : "UTF-8" })
var head = pom.indexOf("<dependencies>")
var tail = pom.indexOf("</dependencies>") + 15
var dependencies = pom.substring( head, tail )
fs.writeFileSync( path.join( out_path, "jar", "dependences.xml") , dependencies )
}).then(function (value) {
return zipjar()
}).then(function (value) {
return zipsample()
}).then(function (value) {
return zipdoc()
}).then(function () {
l.i("打包完成!")
sync('cd .\\public && start .')
}).catch(function (reason) {
l.e( reason )
})
}
main()
-31
View File
@@ -1,31 +0,0 @@
const style = require("./color")
const info = style.green
const error = style.red
const debug = style.cyan
const l = {
o : console.log,
i : function ( msg ) {
console.log('%s%s%s', info[0], msg , info[1]);
},
d : function ( msg ) {
console.log('%s%s%s', debug[0], msg , debug[1]);
},
e : function ( msg ) {
console.log('%s%s%s', error[0], msg , error[1]);
},
}
l.show = function () {
l.i("info")
l.d("debug")
l.e("error")
}
module.exports = l
-5
View File
@@ -1,5 +0,0 @@
v1.11 版本
- 修正不规范接口 GenerateRandom 返回值更改为 String 类型。老版本为 bool 类型,仅于活性检测。
v1.12 版本
- 新增编押验押接口/人行定制接口。
@@ -0,0 +1,109 @@
package com.sunyard;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 管理多线程间对象
* 类似 ThreadLocal
* @param <T>
*/
public class MutiThreadHander<T> {
private static class Handler<T> {
private T obj = null;
private long creatAt = System.currentTimeMillis();
private long lastGetAt = System.currentTimeMillis();
public Handler(T obj) {
this.obj = obj;
}
public T getObj() {
return obj;
}
public long getCreatAt() {
return creatAt;
}
public long getLastGetAt() {
return lastGetAt;
}
}
private final Map<Thread, Handler> handers = new HashMap<Thread, Handler>();
private ScheduledExecutorService gcThread = Executors.newScheduledThreadPool(1);
private long maxLiveMillis = 8 * 3600 * 1000;
private long maxIdleMillis = 3600 * 1000;
private long checkEveryMillis = 5 * 60 * 1000;
public MutiThreadHander() {
gcThread.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
try {
if ( handers.size() <= 0 ) {
return;
}
long now = System.currentTimeMillis();
Iterator<Map.Entry<Thread, Handler>>it = handers.entrySet().iterator();
while ( it.hasNext() ){
Map.Entry<Thread, Handler> entry = it.next();
// check maxLiveMillis
if ( entry.getValue().getCreatAt() - now > maxLiveMillis ){
synchronized ( handers ){
it.remove();
}
}
// check maxIdleMillis
if ( entry.getValue().getLastGetAt() - now > maxIdleMillis ){
synchronized ( handers ){
it.remove();
}
}
}
} catch ( Exception e) {
e.printStackTrace();
}
}
}, checkEveryMillis, checkEveryMillis, TimeUnit.MILLISECONDS );
}
protected T initialValue() {
return null;
}
public void clear(){
synchronized ( handers ) {
handers.remove( Thread.currentThread() );
}
}
public void set(T obj){
synchronized ( handers ) {
handers.put( Thread.currentThread() , new Handler(obj));
}
}
public T get(){
synchronized ( handers ) {
Handler hander = handers.get( Thread.currentThread() );
if ( null == hander ) {
T o = initialValue();
hander = new Handler( o );
handers.put( Thread.currentThread(), hander );
}
return (T) hander.getObj();
}
}
}
@@ -9,7 +9,7 @@ import racal.sunyard.main.SydApi4j;
public class SYMEnDeLongData {
private SydApi4j api;
private String key = "";
private String sykey = "";
private String keyValue = "";
private int keyType = 0;
private int inType = 0;
@@ -95,11 +95,11 @@ public class SYMEnDeLongData {
public String getKey() {
return key;
return sykey;
}
public SYMEnDeLongData setKey(String key) {
this.key = key;
public SYMEnDeLongData setKey(String sykey) {
this.sykey = sykey;
return this;
}
+24 -3
View File
@@ -1,20 +1,23 @@
package com.sunyard;
import com.sunyard.inf.cryption.*;
import com.sunyard.inf.*;
import com.sunyard.inf.customize.Syd4DigitalEnvelope;
import com.sunyard.inf.customize.SydHAApi;
import com.sunyard.inf.customize.SydQNUCApi;
import com.sunyard.inf.customize.SydUnionPayApi;
import racal.sunyard.main.SydApiBuilder;
import java.util.List;
/**
* Created by Cheney on 2017/11/11.
* 程序调用接口
*/
public interface SydApi extends
SydRawApi, SydCertApi, SydCryptionApi, SydGenApi,
SydRawApi, SydCertApi, SydGenApi, SydSYMApi, SydASYMApi, SydHashApi,
SydSVApi, SydHAApi, SydQNUCApi, SydPledge, SydPINOpt,
SydManufactureApi, SydZYOption, SydUnionPayApi {
SydManufactureApi, SydZYOption, SydUnionPayApi ,Syd4DigitalEnvelope{
byte ALG_AES = 0x30;
byte ALG_SM4 = 0x31;
@@ -71,6 +74,18 @@ public interface SydApi extends
*/
SydApi connect(String ip, int port, String pwd, int connectTimeout, int readTimeout);
/**
* 建立到指定地址和端口号的加密设备的TCP/IP 连接,返回 TCP/IP 连接句柄。
* @param ip 加密机 ip
* @param port 加密机端口
* @param pwd 加密机密码,无密码写 null
* @param connectTimeout 网络连接时超时时间
* @param readTimeout 网络通信时,socket 超时时间
* @param retryWhenNetError 网络失败时重试次数
* @return
*/
SydApi connect(String ip, int port, String pwd, int connectTimeout, int readTimeout , int retryWhenNetError);
void init(SydApiBuilder builder);
/**
@@ -89,6 +104,7 @@ public interface SydApi extends
// 单例可以不实现
void error();
/**
* 获取加密机cpu,内存,磁盘使用状况
*
@@ -99,4 +115,9 @@ public interface SydApi extends
RetWrap getStatus();
byte[] directBytes(byte[] data);
public Object getBindObject();
public void setBindObject(Object bindObject);
}
+88 -26
View File
@@ -13,88 +13,129 @@ public class SydApiException extends RuntimeException{
return retCode;
}
public void transMsg(){
switch (this.retCode){
private static String transMsg(int code){
String msg = "未定义的错误";
switch (code){
case -1:
case -2:
case -3:
this.msg = "网络错误";
msg = "网络错误";
break;
case -4:
this.msg = "返回包的序列号有误";
msg = "返回包的序列号有误";
break;
case -5:
this.msg = "返回包的命令码有误";
msg = "返回包的命令码有误";
break;
case -6:
this.msg = "输出缓冲区预留太小";
msg = "输出缓冲区预留太小";
break;
case -25:
this.msg = "输入的 HASH 值长度应该为 32 个字节";
msg = "输入的 HASH 值长度应该为 32 个字节";
break;
case -26:
this.msg = "用户标识超长(应该<=16) ";
msg = "用户标识超长(应该<=16) ";
break;
case -27:
this.msg = "数据类型不合法 ";
msg = "数据类型不合法 ";
break;
case 33:
this.msg = "检索的数据或密钥不存在";
msg = "检索的数据或密钥不存在";
break;
case 4:
this.msg = "DER 编码格式错误(公钥) ";
msg = "DER 编码格式错误(公钥) ";
break;
case 31:
msg = "缓冲区索引错误";
break;
case 0xd:
msg = "公钥加密错误";
break;
case 21:
this.msg = "输入的数据格式错误 ";
msg = "输入的数据格式错误 ";
break;
case 19:
this.msg = "数据解密错(C3) ";
msg = "数据解密错(C3) ";
break;
case 2:
this.msg = "签名验证错误 ";
msg = "签名验证错误 ";
break;
case 129:
this.msg = "没有该指令";
msg = "没有该指令";
break;
case 0x8006 : {
this.msg = "输入的数据格式错误";
msg = "输入的数据格式错误";
break;
}
case 0x7007 : {
msg = "实体白名单未添加";
break;
}
case 0x8004 : {
msg = "证书已过期";
break;
}
case 32770:
this.msg = "签名验证错误(P7) ";
msg = "签名验证错误(P7) ";
break;
case 32773:
this.msg = "证书不可信";
msg = "证书不可信";
break;
case 32884:
this.msg = "证书或签名数据的格式错";
msg = "证书或签名数据的格式错";
break;
case 36868:
this.msg = "DN 所指向的实体不存在";
msg = "DN 所指向的实体不存在";
break;
case 40000:
this.msg = "输入的大数据处理异常";
msg = "输入的大数据处理异常";
break;
case 56300:
msg = "证书导入错误";
break;
case 56307:
msg = "证书删除错误";
break;
case 0xC101 :
msg = "证书识别异常";
break;
default:
this.msg = "未定义的错误";
msg = "未定义的错误";
}
return msg;
}
public void transMsg(){
this.msg = transMsg( this.retCode );
}
public SydApiException(int retCode) {
super("SydApiException(" + "code = "+String.format("%04x", retCode) + ")" );
this.retCode = retCode;
transMsg();
}
public SydApiException(int retCode, Exception e) {
super("SydApiException(" + "code = "+String.format("%04x", retCode) + ")" , e);
this.retCode = retCode;
transMsg();
}
public SydApiException(String msg, int ret){
this(ret);
public SydApiException(String msg, int retCode){
super("SydApiException(" + String.format(" %04X", retCode) + ":" + ( null == msg ? transMsg(retCode) : msg ) + ")" );
this.retCode = retCode;
if (null == msg || "".equals(msg)){
transMsg();
}else {
@@ -102,6 +143,27 @@ public class SydApiException extends RuntimeException{
}
}
public SydApiException(String msg, int retCode, boolean flag){
super(null == msg ? transMsg(retCode) : msg);
this.retCode = retCode;
if (null == msg || "".equals(msg)){
transMsg();
}else {
this.msg = msg;
}
}
public SydApiException(String msg, int ret, Throwable e) {
super("SydApiException(code =" + String.format(" %04x", ret) + " : " + "msg =" + (msg == null ? "未定义的错误" : msg) + ")", e);
this.retCode = ret;
if (msg != null && !"".equals(msg)) {
this.msg = msg;
} else {
this.transMsg();
}
}
public static SydApiException fromBin( byte[] b , String msg){
int code = null != b && b[0] >= 48 && b[0] <= 57 ? Util.a2i( b , 10) : Util.b2i( b );
return new SydApiException(msg, code);
@@ -118,7 +180,7 @@ public class SydApiException extends RuntimeException{
sb.append(Integer.toHexString(this.retCode));
sb.append(" ) ");
sb.append(" msg = ");
sb.append(this.msg);
sb.append(msg);
return sb.toString();
}
}
@@ -0,0 +1,16 @@
package com.sunyard.constant;
/**
* 证书用途
*/
public enum CertUsage {
digitalSignature,
nonRepudiation,
keyEncipherment,
dataEncipherment,
keyAgreement,
keyCertSign,
cRLSign,
encipherOnly,
decipherOnly
}
@@ -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,42 @@
package com.sunyard.entity;
import java.nio.ByteBuffer;
public class MutiReturn7 {
// 返回码
private int ret;
// 0-不是最后 1-是最后
private int isLast;
// 数据
private ByteBuffer data;
public MutiReturn7(int ret, int isLast, ByteBuffer data) {
this.ret = ret;
this.isLast = isLast;
this.data = data;
}
public int getRet() {
return ret;
}
public void setRet(int ret) {
this.ret = ret;
}
public int getIsLast() {
return isLast;
}
public void setIsLast(int isLast) {
this.isLast = isLast;
}
public ByteBuffer getData() {
return data;
}
public void setData(ByteBuffer data) {
this.data = data;
}
}
@@ -0,0 +1,86 @@
package com.sunyard.entity;
import java.util.List;
public class ServerConfig {
/**
* 主机节点信息
*/
private List<ServerAddress> masterNodeList;
/**
* 备机节点信息
*/
private List<ServerAddress> slaveNodeList;
/**
* 连接超时时间
*/
private Integer timeout;
public ServerConfig(List<ServerAddress> masterNodeList, List<ServerAddress> slaveNodeList, Integer timeout) {
this.masterNodeList = masterNodeList;
this.slaveNodeList = slaveNodeList;
this.timeout = timeout;
}
public List<ServerAddress> getMasterNodeList() {
return masterNodeList;
}
public void setMasterNodeList(List<ServerAddress> masterNodeList) {
this.masterNodeList = masterNodeList;
}
public Integer getTimeout() {
return timeout;
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
public List<ServerAddress> getSlaveNodeList() {
return slaveNodeList;
}
public void setSlaveNodeList(List<ServerAddress> slaveNodeList) {
this.slaveNodeList = slaveNodeList;
}
public static class ServerAddress {
private String ip;
private Integer port;
public ServerAddress(String ip, Integer port) {
this.ip = ip;
this.port = port;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
}
@@ -0,0 +1,103 @@
package com.sunyard.entity;
/**
* SM2加密解密时间统计类
* 用于记录发送、计算、接收三个阶段的耗时
*/
public class TimeStats {
// 发送阶段总耗时(毫秒)- 循环发送数据块的时间
private long sendTime;
// 计算阶段耗时(毫秒)- 执行加密/解密计算的时间
private long computeTime;
// 接收阶段总耗时(毫秒)- 循环接收数据块的时间
private long receiveTime;
// 发送次数
private int sendCount;
// 接收次数
private int receiveCount;
public TimeStats() {
this.sendTime = 0;
this.computeTime = 0;
this.receiveTime = 0;
this.sendCount = 0;
this.receiveCount = 0;
}
public long getSendTime() {
return sendTime;
}
public void setSendTime(long sendTime) {
this.sendTime = sendTime;
}
public long getComputeTime() {
return computeTime;
}
public void setComputeTime(long computeTime) {
this.computeTime = computeTime;
}
public long getReceiveTime() {
return receiveTime;
}
public void setReceiveTime(long receiveTime) {
this.receiveTime = receiveTime;
}
public int getSendCount() {
return sendCount;
}
public void setSendCount(int sendCount) {
this.sendCount = sendCount;
}
public int getReceiveCount() {
return receiveCount;
}
public void setReceiveCount(int receiveCount) {
this.receiveCount = receiveCount;
}
/**
* 获取总耗时
*/
public long getTotalTime() {
return sendTime + computeTime + receiveTime;
}
/**
* 获取各阶段耗时占比
*/
public double getSendPercentage() {
long total = getTotalTime();
return total == 0 ? 0 : (double) sendTime / total * 100;
}
public double getComputePercentage() {
long total = getTotalTime();
return total == 0 ? 0 : (double) computeTime / total * 100;
}
public double getReceivePercentage() {
long total = getTotalTime();
return total == 0 ? 0 : (double) receiveTime / total * 100;
}
@Override
public String toString() {
return String.format(
"TimeStats{sendTime=%dms(%.1f%%), computeTime=%dms(%.1f%%), receiveTime=%dms(%.1f%%), total=%dms, sendCount=%d, receiveCount=%d}",
sendTime, getSendPercentage(),
computeTime, getComputePercentage(),
receiveTime, getReceivePercentage(),
getTotalTime(),
sendCount, receiveCount
);
}
}
@@ -3,8 +3,10 @@ package com.sunyard.inf;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
import com.sunyard.constant.CertUsage;
import java.io.UnsupportedEncodingException;
import java.util.List;
/**
* 证书操作相关接口
@@ -101,6 +103,14 @@ public interface SydCertApi {
String sign
);
/**
* 查询所有证书
* @return
* certDNs: 证书DN
*/
List<String> getAllCert() throws UnsupportedEncodingException;
/**
* 查询所有证书
* @param dataFlag 数据包标志 0:起始包 1:中间包 2:结束包
@@ -114,20 +124,57 @@ public interface SydCertApi {
*/
RetWrap getAllCert(int dataFlag) throws UnsupportedEncodingException;
/**
* 查询所有证书
* @param dataFlag 数据包标志 0:起始包 1:中间包 2:结束包
* @param sqlite 查询条件,默认查询所有"1=1"
* @return
* dataFlag: 数据包标志 0:起始包 1:中间包 2:结束包
* certAllNum: 证书总数
* realCertNum: 实际证书个数
* dataAttrFlag: 数据包属性标志
* certLenMax: 证书最大长度
* certDNs: 证书DN
*/
RetWrap getAllCert(int dataFlag,String sqlite) throws UnsupportedEncodingException;
/**
* 上传指定证书到加密设备
* @param certData 证书的字节数组
* @param organizationId 机构号的字节数组
* @param us 白名单类型
* @return
*/
RetWrap importCert(byte[] certData, byte[] organizationId, CertUsage... us);
RetWrap importCert(byte[] certData, byte[] organizationId);
String importCert(String cert);
/**
* 从加密设备中删除指定 DN 的公钥证书
* @param dn:传入的证书
*
* @return
*/
boolean deleteCert(String dn);
/**
* 上传指定证书到加密设备,并在证书前后加上begin和end
* @param certData 证书的字节数组
* @param organizationId 机构号的字节数组
* @param us 白名单类型
* @return
*/
RetWrap importCertAddHT(String certData, byte[] organizationId, CertUsage... us);
RetWrap importCertAddHT(String certData, byte[] organizationId);
String getCertByDn(String dn) throws UnsupportedEncodingException;
String getCertByDn(String dn,int type) throws UnsupportedEncodingException;
public String getCertByDn(byte[] dnBytes);
}
@@ -38,6 +38,14 @@ interface SydHashApi {
*/
byte[] SM3Hash(String publicKey, byte[] msg, int block, byte[] mac);
/**
* 计算SM3散列值
* @param publicKey 公钥的 DER 编码 (03420004 开头)
* @param userId 用户ID
* @param msg 原始数据,二进制的消息块
* @return
*/
byte[] SM3Hash(String publicKey, String userId, byte[] msg);
/**
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
@@ -0,0 +1,216 @@
package com.sunyard.inf;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
/**
* 不带原文的签名验签
*/
public interface SydDetachedSVApi {
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
public boolean SYD_DetachedVerify(
byte[] orgData,
String sign);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String SYD_DetachedSign(
byte[] orgData,
String sCertDN
);
/**
* 人行项目需要RSA支持
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String SYD_DetachedSign(
int rFlag,
byte[] orgData,
String sCertDN
);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 待签名的原始数据将在接口内部进行 sm3 ,然后做 Detach 签名
* @param orgData 待签名的原始数据
* @param publicKey sm3 hash 所用的公钥
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String sm3AndDetachedSign(
byte[] orgData,
String publicKey,
String sCertDN
);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 原始数据将在接口内部进行 sm3 ,然后做 Detach 验签
* @param orgData 待签名的原始数据
* @param publicKey sm3 hash 所用的公钥
* @param sign 签名数据
* @return 验签是否通过
*/
public boolean sm3AndDetachedVerify(
byte[] orgData,
String publicKey,
String sign);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 待签名的原始数据将在接口内部进行不带公钥的 sm3 ,然后做 Detach 签名
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
String sm3WithoutPKDetachedSign(byte[] orgData, String sCertDN);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 原始数据将在接口内部进行无公钥的 sm3 ,然后做 Detach 验签
*
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean sm3WithoutPKDetachedVerify(byte[] orgData, String sign);
/**
*
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 数据模式,输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 输入的数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String detachedSign(
int dataType,
byte[] orgData,
String sCertDN
);
//SM2与RSA兼容
public String detachedSignAll(int rFlag,byte[] orgData, String sCertDN);
//SM2与RSA兼容
public boolean detachedVerifyAll(int rFlag,byte[] orgData, String sign);
/**
* 带公钥证书与签名属性的数字签名(遵循 PKCS#7)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为数据
* @param keyTag 密钥对应的索引号
* @return 签名的 DER 编码
*/
public byte[] detachedSign(
int dataType,
byte[] orgData,
int keyTag
);
public String detachedSign(int rFlag,int dataType, byte[] orgData, String sCertDN);
/**
* 带公钥证书的PKCS#7数字签名(序列号)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为要签名的信息
* @param certificateNo X509证书序号
* @return 符合PKCS7标准的签名结果
*/
public String detachedSignbysn(
int dataType,
byte[] orgData,
String certificateNo);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean detachedVerify(
int dataType,
byte[] orgData,
String sign);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
*
* @param rFlag RSA标识
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean detachedVerify(
int rFlag,
int dataType,
byte[] orgData,
String sign);
/**
* 带公钥证书与签名属性的数字签名验签(遵循 PKCS#7)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为数据
* @param sign 已签名数据
* @return 是否正确
*/
boolean detachedVerify(
int dataType,
byte[] orgData,
byte[] sign);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)返回证书信息
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 证书
*/
X509 detachedVerifyAndGetX509(int dataType,
byte[] orgData,
String sign);
/**
* 计算SM3散列值
* @param packSn 消息块号,0=仅一块,1=第一块,2=中间块,3=最后块
* @param userId 用户 ID,只对“消息块号”为 0、1 时有效
* @param publicKey 公钥的 DER 编码
* @param msg 二进制的消息块
* @param filterData 过渡消息数据,只对“消息块号”为 2、3 时有效
* @return
* filterData: 过渡消息数据,只对“消息块号”为 2、1 时有效
* hash: hash
*/
RetWrap SM3Hash(int packSn, String userId, byte[] publicKey, byte[] msg, byte[] filterData);
}
+37 -3
View File
@@ -132,6 +132,18 @@ public interface SydGenApi {
*/
RetWrap SM2GenSessionKey(String publicKey);
/**
* 此函数用于会话密钥的产生,用于发起端。
* 加密机产生随机会话密钥,输出两类密文:
* 1、 RSA公钥加密的密文,用于密钥的传递。
* 2、 本地 LMK 加密,用于本地应用数据的加解密。
*
* @param publicKey 公钥串,DER 编码,HEX 格式。
* @return CipherKey 公钥加密的会话密钥,DER 编码,HEX 格式, SessionKey 本地LMK 加密的会话密钥,HEX 格式 , KCV 会话密钥的检验值,HEX 格式,长度为 16H
*/
RetWrap RSAGenSessionKey(String publicKey);
/**
* 生成数字信封
* @param publicKey 公钥
@@ -226,7 +238,12 @@ public interface SydGenApi {
* SessionKey 本地LMK 加密的会话密钥,HEX 格式, 本地 LMK 加密的会话密钥长度,HEX 格式(不包括第 1 个字符),一般为 33 个 Bytes。默认输入值为缓冲区的大小。
* KCV 会话密钥的检验值,HEX 格式,长度为 32H。
*/
RetWrap generateDEByDn(String certSerial, String oData);
RetWrap generateDEByDn(String certSerial, byte[] oData);
RetWrap generateDEByDnICBC(String certSerial,String iv, byte[] oData,int roundmod);
RetWrap generateDEByDnRSA(int alg,String certSerial, byte[] oData);
/**
* 产生对称密钥,通过公钥加密生成网联格式的数字信封。
@@ -240,7 +257,7 @@ public interface SydGenApi {
* SessionKey 本地LMK 加密的会话密钥,HEX 格式, 本地 LMK 加密的会话密钥长度,HEX 格式(不包括第 1 个字符),一般为 33 个 Bytes。默认输入值为缓冲区的大小。
* KCV 会话密钥的检验值,HEX 格式,长度为 32H。
*/
RetWrap generateDE(byte[] certSerial, int alg, int model, String oData);
RetWrap generateDE(byte[] certSerial, int alg, int model, byte[] oData);
/**
* 产生对称密钥,通过公钥加密生成网联格式的数字信封。
@@ -308,8 +325,10 @@ public interface SydGenApi {
* KCV 会话密钥的检验值,HEX 格式,长度为 36H。
* orgCode 如果有机构码的话会返回机构码
*/
RetWrap decryptDEByDN(String certSerial, String pCipherKey);
RetWrap decryptDEByDN(String certSerial, byte[] pCipherKey);
RetWrap decryptDEByDNICBC(String certSerial, String IV,String pCipherKey,int roundmod);
RetWrap decryptDEByDNRSA(int alg,String certSerial, byte[] pCipherKey);
/**
* 接收用私钥解密数字信封,还原对称密钥。
*
@@ -325,6 +344,21 @@ public interface SydGenApi {
*/
RetWrap decryptDE(boolean pFlag, int model, byte[] certSerial, String pCipherKey);
/**
* 接收用RSA私钥解密数字信封,还原对称密钥。
*
* @param pFlag 输入。 p标识,如果为true,则传入R
* @param model 输入。 证书模式,0:证书序号,1:证书 DN
* @param certSerial 输入。 对方 X509 证书的序列号或DN。
* @param pCipherKey 输入。 公钥加密的会话密钥,BASE64 编码
* @return RetWrap 包含 SessionKey KCV
* oData 如果有机构码的话会返回原数据
* SessionKey 输出。 本地LMK 加密的会话密钥,格式为:密钥类型|密钥密文,比如:02|密钥密文
* KCV 会话密钥的检验值,HEX 格式,长度为 36H。
* orgCode 如果有机构码的话会返回机构码
*/
RetWrap decryptDERSA(boolean pFlag, int model, byte[] certSerial, String pCipherKey);
/**
* 产生要求长度的随即数据串,可用于身份认证
*
@@ -0,0 +1,122 @@
package com.sunyard.inf;
import com.sunyard.SydApiException;
/**
* 不经过 CA 授信
* 直接使用公私钥对签名验签
*/
interface SydNakedSVApi {
/**
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public byte[] SYD_NakedSign(
byte[] orgData,
String sCertDN
);
/**
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
* 人行项目增加RSA
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public byte[] SYD_NakedSign(
int rFlag,
byte[] orgData,
String sCertDN
);
/**
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @param sCertDN 签名者证书 DN
* @return 验签是否通过
*/
public boolean SYD_NakedVerify(
byte[] orgData,
byte[] sign,
String sCertDN
);
/**
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @param sCertDN 签名者证书 DN
* @return 验签是否通过
*/
public boolean SYD_NakedVerify(
int rFlag,
byte[] orgData,
byte[] sign,
String sCertDN
);
/**
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
* @param rFlag 摘要算法 1—DIGEST_ALGO_MD5 M
* 2—DIGEST_ALGO_SHA1 S
* 3—DIGEST_ALGO_SHA256 R
* 4-SM2 国密证书,SM3算法
* S代表RSA-SHA1进行签名,如果为R代表RSA-SHA256进行签名,如果为M代表RSA-MD5进行签名
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public byte[] SYD_NakedSignAll(
int rFlag,
byte[] orgData,
String sCertDN
);
/**
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
* @param rFlag 摘要算法 1—DIGEST_ALGO_MD5 M
* * 2—DIGEST_ALGO_SHA1 S
* * 3—DIGEST_ALGO_SHA256 R
* 4-SM2 国密证书,SM3算法
* * S代表RSA-SHA1进行签名,如果为R代表RSA-SHA256进行签名,如果为M代表RSA-MD5进行签名
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @param sCertDN 签名者证书 DN
* @return 验签是否通过
*/
public boolean SYD_NakedVerifyAll(
int rFlag,
byte[] orgData,
byte[] sign,
String sCertDN
);
/**
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1) 安徽农信定制接口
* @param cert 上传证书
* @param rFlag 摘要算法 1—DIGEST_ALGO_MD5 M
* * 2—DIGEST_ALGO_SHA1 S
* * 3—DIGEST_ALGO_SHA256 R
* 4-SM2 国密证书,SM3算法
* * S代表RSA-SHA1进行签名,如果为R代表RSA-SHA256进行签名,如果为M代表RSA-MD5进行签名
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @param sCertDN 签名者证书 DN
* @return 验签是否通过
*/
public boolean SYD_NakedVerifyAll4NX (
String cert,
int rFlag,
byte[] orgData,
byte[] sign,
String sCertDN
) ;
}
+3 -384
View File
@@ -3,6 +3,9 @@ package com.sunyard.inf;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
import com.sunyard.inf.sva.SydAttachedSVApi;
import java.io.UnsupportedEncodingException;
/**
* 签名验签相关接口
@@ -11,389 +14,5 @@ public interface SydSVApi extends SydNakedSVApi, SydAttachedSVApi, SydDetachedSV
}
/**
* 不经过 CA 授信
* 直接使用公私钥对签名验签
*/
interface SydNakedSVApi {
/**
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public byte[] SYD_NakedSign(
byte[] orgData,
String sCertDN
);
/**
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @param sCertDN 签名者证书 DN
* @return 验签是否通过
*/
public boolean SYD_NakedVerify(
byte[] orgData,
byte[] sign,
String sCertDN
);
}
/**
* 带原文的签名验签
*/
interface SydAttachedSVApi {
/**
* sm2私钥签名
* 用户id默认为1234567812345678
* 签名结果R/S序列串先进行der编码,再进行base64编码
*
* @param flag 私钥标志位,当为1时第二个参数传入存储私钥的索引,当为0时第二个参数传入私钥
* @param privateKey 当私钥标志位为1时传入存储私钥的索引,当为0时传入私钥
* @param publicKey 公钥
* @param orgData 要签名的信息
* @return 签名结果
*/
String SM2SignC(int flag, String privateKey, byte[] publicKey, byte[] orgData);
String SM2SignC(int flag, String pUserID, String privateKey, byte[] publicKey, byte[] orgData);
/**
* SM2 私钥签名
* @param pUserID 使用者的 ID,最大长度为 16 位数字,右对齐。
* @param certNo 证书号
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据
* @param publicKey 公钥的 DER 编码
* @param orgData 原始数据
* @return 签名的 base64 编码
*/
String SM2SignC(
String pUserID,
String certNo,
int nOrgDataType,
byte[] publicKey,
byte[] orgData
);
/**
* RSA 私钥签名
* @param HashMark 哈希标识 指示用于哈希证书数据的哈希算法的标识。0: SHA1 1: SHA256 2: MD5。
* @param privateKeyTag 私钥标记 指示私钥位置的标记。数字为存储私钥的索引,除了全9表示使用由命令中提供的密钥。
* 27位的索引号:16位机构号+3位密钥类型+8位密钥索引号
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据
* @param orgData 原始数据
* @return 签名的 base64 编码
*/
byte[] RSASignC(
String privateKeyTag,
int HashMark,
int nOrgDataType,
byte[] orgData);
byte[] RSASign(
String privateKey,
int HashMark,
int nOrgDataType,
byte[] orgData);
/**
* 采用 RSA 算法,用指定的公钥对指定的原始数据进行数字签名验证。
* @param HashMark 哈希标识
* @param nOrgDataType 签名方式
* @param publicKey 公钥
* @param orgData 原始数据
* @param sign base64 格式的签名
* @return true 验签通过 false 验签失败
*/
boolean RSAVerify(
int HashMark,
int nOrgDataType,
byte[] publicKey,
byte[] orgData,
byte[] sign);
/**
* sm2验签
* 用户id默认为1234567812345678
*
* @param publicKey 公钥的 DER 编码
* @param orgData 要签名的信息
* @param base64Sign 计算的签名,签名结果R/S序列串先进行der编码,再进行base64编码后的结果
* @return true 验签成功,false 验签失败
*/
boolean SM2Verify(byte[] publicKey, byte[] orgData, String base64Sign);
/**
* 采用 SM2 算法,用指定的公钥对指定的原始数据进行数字签名验证。
* @param certNo id 用于计算SM3-HASH
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据,用1.2.3章节限定符亦可
* @param publicKey 公钥
* @param orgData 原始数据
* @param sign base64 格式的签名
* @return true 验签通过 false 验签失败
*/
boolean SM2Verify(
String certNo,
int nOrgDataType,
byte[] publicKey,
byte[] orgData,
String sign
);
/**
* SM2 私钥签名
* @param certNo 证书号
* @param orgData 原始数据
* @return 签名的 base64 编码
*/
String SM2SignCustomized(
String certNo,
byte[] orgData
);
/**
* 采用 SM2 算法,用指定的公钥对指定的原始数据进行数字签名验证。
* @param certNo 证书号
* @param orgData 原始数据
* @param sign base64 格式的签名
* @return true 验签通过 false 验签失败
*/
boolean SM2VerifyCustomized(
String certNo,
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 true 验签通过 false 验签失败
*/
boolean attachedVerify(String sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return 成功返回签名的原数据,失败则报错
*/
String attachedVerifyRD(String sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return
* 若发送报文返回证书信息标志位为0,则返回已签名数据,
* 若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据
*/
X509 attachedVerifyAndGetX509(String sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return
* 若发送报文返回证书信息标志位为0,则返回已签名数据,
* 若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据
*/
RetWrap attachedVerifyAndGetAll(String sign);
}
/**
* 不带原文的签名验签
*/
interface SydDetachedSVApi {
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
public boolean SYD_DetachedVerify(
byte[] orgData,
String sign);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String SYD_DetachedSign(
byte[] orgData,
String sCertDN
);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 待签名的原始数据将在接口内部进行 sm3 ,然后做 Detach 签名
* @param orgData 待签名的原始数据
* @param publicKey sm3 hash 所用的公钥
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String sm3AndDetachedSign(
byte[] orgData,
String publicKey,
String sCertDN
);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 原始数据将在接口内部进行 sm3 ,然后做 Detach 验签
* @param orgData 待签名的原始数据
* @param publicKey sm3 hash 所用的公钥
* @param sign 签名数据
* @return 验签是否通过
*/
public boolean sm3AndDetachedVerify(
byte[] orgData,
String publicKey,
String sign);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 待签名的原始数据将在接口内部进行不带公钥的 sm3 ,然后做 Detach 签名
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
String sm3WithoutPKDetachedSign(byte[] orgData, String sCertDN);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 原始数据将在接口内部进行无公钥的 sm3 ,然后做 Detach 验签
*
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean sm3WithoutPKDetachedVerify(byte[] orgData, String sign);
/**
*
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 数据模式,输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 输入的数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String detachedSign(
int dataType,
byte[] orgData,
String sCertDN
);
/**
* 带公钥证书与签名属性的数字签名(遵循 PKCS#7)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为数据
* @param keyTag 密钥对应的索引号
* @return 签名的 DER 编码
*/
public byte[] detachedSign(
int dataType,
byte[] orgData,
int keyTag
);
/**
* 带公钥证书的PKCS#7数字签名(序列号)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为要签名的信息
* @param certificateNo X509证书序号
* @return 符合PKCS7标准的签名结果
*/
public String detachedSignbysn(
int dataType,
byte[] orgData,
String certificateNo);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean detachedVerify(
int dataType,
byte[] orgData,
String sign);
/**
* 带公钥证书与签名属性的数字签名验签(遵循 PKCS#7)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为数据
* @param sign 已签名数据
* @return 是否正确
*/
boolean detachedVerify(
int dataType,
byte[] orgData,
byte[] sign);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)返回证书信息
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 证书
*/
X509 detachedVerifyAndGetX509(int dataType,
byte[] orgData,
String sign);
/**
* 计算SM3散列值
* @param packSn 消息块号,0=仅一块,1=第一块,2=中间块,3=最后块
* @param userId 用户 ID,只对“消息块号”为 0、1 时有效
* @param publicKey 公钥的 DER 编码
* @param msg 二进制的消息块
* @param filterData 过渡消息数据,只对“消息块号”为 2、3 时有效
* @return
* filterData: 过渡消息数据,只对“消息块号”为 2、1 时有效
* hash: hash
*/
RetWrap SM3Hash(int packSn, String userId, byte[] publicKey, byte[] msg, byte[] filterData);
}
@@ -0,0 +1,135 @@
package com.sunyard.inf.cryption;
public interface SydASYMApi {
/**
* 非对称加解密接口
*/
/**
* 用指定的 SM2 公钥对指定的密文数据进行加密。
*
* @param publicKey 公钥钥串,DER 编码,HEX 格式。
* @param pOrgData 加密的数据。
* @return 加密的数据 base64 编码。
*/
String SM2Encrypt(
byte[] publicKey,
byte[] pOrgData
);
/**
* 用指定的 SM2 公钥对指定的密文数据进行加密。
*
* @param publicKey 公钥钥串,DER 编码,HEX 格式。
* @param pOrgData 加密的数据。
* @return 加密的数据 der 编码。
*/
byte[] SYD_SM2_Encrypt(byte[] publicKey, byte[] pOrgData);
/**
* 用指定的 SM2 公钥对指定的密文数据进行加密。
* 输出的sm2密文结构为C1C2C3格式
* @param publicKey 公钥钥串,DER 编码,HEX 格式。
* @param pOrgData 加密的数据。
* @return 加密的数据 base64 编码。
*/
String SM2EncryptOrder(byte[] publicKey, byte[] pOrgData);
/**
* 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
*
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
* @param pEnData 加密的数据,base64 编码。
* @return 明文数据。
*/
byte[] SM2DecryptC(String userId, String pEnData);
/**
* 使用外部私钥解密
* @param sk LMK下加密的私钥
* @param enData 密文数据(base64 编码)
* @return 解密结果
*/
byte[] SM2Decrypt(byte[] sk, String enData);
/**
* 使用外部私钥解密
* @param sk LMK下加密的私钥
* @param enData 密文数据(DER 编码)
* @return 解密结果
*/
byte[] SYD_SM2_Decrypt(byte[] sk, byte[] enData);
/**
* 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
* 输入的sm2密文结构为C1C2C3格式
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
* @param enData 加密的数据,base64 编码。
* @param keyType 密钥类型,0:签名证书, 1:加密证书。
* @return 明文数据。
*/
byte[] SM2DecryptOrder(String userId, String enData, int keyType);
/**
* 用指定的 RSA 私钥对指定的密文数据进行加密。
*
* @param publicKey 私钥串,DER 编码,HEX 格式。
* @param pOrgData 加密的数据。
* @return 加密的数据 base64 编码。
*/
String RSAEncrypt(
String publicKey,
byte[] pOrgData
);
/**
* 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
*
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
* @param pEnData 加密的数据,base64 编码。
* @return 明文数据。
*/
byte[] RSADecryptC(
String userId,
String pEnData
) throws Exception;
/**
* 使用外部私钥解密
* @param sk
* @param enData
* @return
*/
public byte[] RSADecrypt(String sk, String enData) throws Exception;
/**
* 非对称公钥加密
* @param alg 算法标识,0 = RSA 1 = SM2
* @param pk 公钥的 DER 编码
* @param data 数据
* @return 公钥加密的密文的 DER 编码(对于 RSA 算法,数据类型为 BIT).
*/
public byte[] encryptByPk(int alg, String pk, byte[] data);
/**
* 非对称私钥解密
* @param alg 算法标识:0 = RSA 1 = SM2
* @param sk 私钥值,LMK下加密的私钥
* @param data 密文数据(DER 编码)
* @return 公钥加密的密文的 DER 编码(对于 RSA 算法,数据类型为 BIT)
*/
public byte[] decryptBySk(int alg, String sk, byte[] data);
/**
* 非对称私钥解密
* @param alg 算法标识:0 = RSA 1 = SM2
* @param userId 16位机构号
* @param data 密文数据(DER 编码)
* @return 公钥加密的密文的 DER 编码(对于 RSA 算法,数据类型为 BIT).
*/
public byte[] decryptBySkC(int alg, String userId, byte[] data);
}
@@ -0,0 +1,77 @@
package com.sunyard.inf.cryption;
import com.sunyard.RetWrap;
/**
* Hash 算法接口
*/
public interface SydHashApi {
/**
* 计算SM3散列值
* @param sn 证书序号
* @param userId 用户ID
* @param msg 原始数据,二进制的消息块
* @return
*/
// byte[] SM3HashSNaId(String sn, String userId, byte[] msg);
/**
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
* @param publicKey 公钥的 DER 编码(可以为空)
* @param msg 原始数据,二进制的消息块
* @param block 消息块标志
* @param mac 上一轮 mac 值,当 mac 不是 null,长度不为 0,则直接从第二包开始。
* @return HASH 值,32 个 Bytes.
*/
byte[] SM3Hash(String publicKey, byte[] msg, int block, byte[] mac);
/**
* 计算SM3散列值
* @param publicKey 公钥的 DER 编码 (03420004 开头)
* @param userId 用户ID
* @param msg 原始数据,二进制的消息块
* @return
*/
byte[] SM3Hash(String publicKey, String userId, byte[] msg);
/**
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
*
* @param publicKey 公钥(可以为空)
* @param msg 原始数据
* @return HASH 值,32 个 Bytes.
*/
byte[] SM3Hash(String publicKey, byte[] msg);
/**
* 输入对指定的原始数据 (无公钥),通过 SM3 算法计算数据的散列值。
*
* @param msg 原始数据
* @return HASH 值,32 个 Bytes.
*/
byte[] SM3Hash(byte[] msg);
public byte[] MACCalc(int alg, int keyType, int fullmode, int maclen, String key, byte[] infoData);
/**
* mac 计算
* @param alg 0=DES 1=3DES 2=SM4 3=AES 4=IDEA 5=SM1 6=3DES-X9.19
* @param keyType 0-TAK 1-ZAK
* @param fullMode 0-弱填充 1 强填充
* @param AK 密钥
* @param infoData <=1024
* @param macLen 1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效)
* @return mac 值 hex 格式
*/
public String MACCalc(int alg, int keyType, String AK, int fullMode, byte[] infoData, int macLen);
public void MACCheck(int alg, int keyType, String AK, int fullMode, byte[] infoData, String mac);
public String calcPBOCMAC(int mode, int keyType, String key, byte[] data, int block, byte[] iv);
public RetWrap countHash(int hashType, int packSn, byte[] msg, byte[] filterData);
public byte[] itHash(int hashType, byte[] orgData);
}
@@ -0,0 +1,282 @@
package com.sunyard.inf.cryption;
import com.sunyard.RetWrap;
import java.io.UnsupportedEncodingException;
/**
* 对称加解密接口
*/
public interface SydSYMApi {
/**
* E0 指令复合接口
* @param isEn 指定加解密,true为加密,false为解密
* @param nAlg 密钥模式,当isEn为true时,默认为SM4加密,0为DES加密,1为AES256 加密。当isEn为false时,默认为SM4解密,0为DES解密,1为AES256解密
* @param seesionKey 密钥
* @param roundmod 轮模式,密钥加密模式:1=ECB,2=CBC,3=CFB,4=OFB
* @param fullMode 填充模式:0为饥饿模式,1为贪婪模式
* @param pInData 消息数据
* @param iv IV
* @param block 消息块号
* @return
* iv: IV 数据域
* msg_all: 消息数据
*/
RetWrap SYMEnDeData(Boolean isEn, int nAlg, String seesionKey, int roundmod, int fullMode, byte[] pInData, byte[] iv, int block);
/**
* 用输入的会话密钥,对指定报文数据进行加密处理。填充模式为1
*
* @param nAlg 算法标识., 0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param pINdata 要加密的报文明文。必须是 8 或16 的倍数。
* @return 输出的报文密文, 长度为报文明文 + 16
*/
byte[] SYMEncryptData(int nAlg, String seesionKey, byte[] pINdata);
/**
* 对指定报文数据进行SM4加密
* @param type 密钥类型。0: ZEK,1: TEK
* @param userId 生成密钥时的机构号。
* @param index 密钥索引
* @param data 待加密的数据
* @return
*/
byte[] SYMSM4EncDataByIndex(int type, String userId, String index, byte[] data);
/**
* 用输入的会话密钥,对指定报文数据进行加密处理。
*
* @param nAlg 算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param fullmode 填充模式:0为饥饿模式,1为贪婪模式
* @param pINdata 要加密的报文明文。必须是 8 或16 的倍数。
* @return 输出的报文密文, 长度为报文明文 + 16
*/
byte[] SYMEncryptData(int nAlg, String seesionKey, int fullmode, byte[] pINdata);
// List<byte[]> SYMEncryptDecryptBatchData(int nAlg, String[] seesionKey, int fullmode, List<byte[]> pINdata);
/**
* 用输入的会话密钥,对指定报文数据进行加密处理。
*
* @param nAlg 算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param pInData 要加密的报文明文。必须是 8 或16 的倍数。
* @return 输出的报文密文, 长度为报文明文 + 16
*/
byte[] SYMEncryptData_nofill(int nAlg, String seesionKey, byte[] pInData);
/**
* 用输入的会话密钥,对指定报文数据进行解密处理。填充模式为1
*
* @param nAlg  算法标识.0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数。
* @return 输出的报文明文。
*/
byte[] SYMDecryptData(int nAlg, String seesionKey, byte[] pINdata);
/**
* 用输入的会话密钥,对指定报文数据进行解密处理。
*
* @param nAlg  算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param fullmode 填充模式:0为饥饿模式,1为贪婪模式
* @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数。
* @return 输出的报文明文。
*/
byte[] SYMDecryptData(int nAlg, String seesionKey, int fullmode, byte[] pINdata);
/**
* 用输入的会话密钥,对指定报文数据进行解密处理。
*
* @param nAlg  算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param pInData 要解密的报文密文。长度必须是8 或16 的倍数。
* @return 输出的报文明文。
*/
byte[] SYMDecryptData_nofill(int nAlg, String seesionKey, byte[] pInData);
/**
* 加解密数据(E1)
* @param nAlg 密钥模式,默认为SM4解密,0:DES加密,1:AES256 解密
* @param seesionKey 密钥
* @param inputPath 输入消息数据的文件路径
* @param outputPath 输出消息数据的文件路径
* @return
*/
boolean SYMDecryptDataWithFile(int nAlg, String seesionKey, String inputPath, String outputPath) throws Exception;
/**
* 使用SM4算法进行加密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
* @param keyType 密钥类型 0: ZEK,1: TEK
* @param key 密钥
* @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
* @param inFilePath 需要加密的数据文件所在的路径
* @param outFilePath 加密后的密文数据将要保存的文件路径
* @return 加密是否成功。false为失败,true为成功
*/
boolean SM4EncryptFileDataCBC(int keyType, String key, int inType, int outType, String inFilePath, String outFilePath);
/**
* 使用SM4算法进行加密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
* @param keyType 密钥类型 0: ZEK,1: TEK
* @param key 密钥
* @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
* @param msg 消息数据
* @return 输出的报文密文
*/
byte[] SM4EncryptDataCBC(int keyType, String key, int inType, int outType, byte[] msg);
/**
* 使用SM4算法进行解密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
* @param keyType 密钥类型 0: ZEK,1: TEK
* @param key 密钥
* @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
* @param inFilePath 加密后的密文数据将要保存的文件路径
* @param outFilePath 解密后的数据文件所在的路径
* @return 解密是否成功。false为失败,true为成功
*/
boolean SM4DecryptFileDataCBC(int keyType, String key, int inType, int outType, String inFilePath, String outFilePath) throws UnsupportedEncodingException;
/**
* 使用SM4算法进行解密,其中加密模式为CBC,
* Ⅳ使用缺省值0X 00000000000000000000000000000000,
* 补位模式为 PKCS5 PADDING 。
* @param keyType 密钥类型 0: ZEK,1: TEK
* @param key 密钥
* @param inType 输入消息类型 0:二进制 1:扩展十六进制
* @param outType 输出消息类型 0:二进制 1:扩展十六进制
* @param msg 加密后的消息数据
* @return 输出的报文明文
*/
byte[] SM4DecryptDataCBC(int keyType, String key, int inType, int outType, byte[] msg);
/**
* 用输入的会话密钥,对指定报文数据进行加密处理。
*
* @param nAlg  算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey  本地LMK 加密的会话密钥,HEX 格式
* @param pINdata  要加密的报文明文。必须是 8 或16 的倍数。
* @return 输出的报文密文, 长度为报文明文 + 16
*/
byte[] SYMEncryptDataCBC(int nAlg, String seesionKey, byte[] pINdata);
/**
* 用输入的会话密钥,对指定报文数据进行加密处理。
*
* @param nAlg  算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey  本地LMK 加密的会话密钥,HEX 格式
* @param fullmode  填充模式:0为饥饿模式,1为贪婪模式
* @param pInData  要加密的报文明文。必须是 8 或16 的倍数。
* @return 输出的报文密文, 长度为报文明文 + 16
*/
byte[] SYMEncryptDataCBC(int nAlg, String seesionKey, int fullmode, byte[] pInData);
/**
* 用输入的会话密钥,对指定报文数据进行解密处理。
*
* @param nAlg  算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数。
* @return 输出的报文明文。
*/
byte[] SYMDecryptDataCBC(int nAlg, String seesionKey, byte[] pINdata);
/**
* 用输入的会话密钥,对指定报文数据进行解密处理。
*
* @param nAlg  算法标识.,0x00:3DES,0x01:SM4。
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
* @param fullmode 填充模式:0为饥饿模式,1为贪婪模式
* @param pInData 要解密的报文密文。长度必须是8 或16 的倍数。
* @return 输出的报文明文。
*/
byte[] SYMDecryptDataCBC(int nAlg, String seesionKey, int fullmode, byte[] pInData);
/**
* 用输入的会话密钥,对指定报文数据进行解密处理。
*
* @param srcKey  源秘钥.十六进制字符串。
* @param desKey  目的秘钥.十六进制字符串。
* @param sca  源算法SCA.Int类型。
* @param sPin  源PIN块.十六进制字符串。
* @param primaryAccount  主账号.十六进制字符串。
* @return 目的Pin块。
*/
byte[] transPinFrOneKeyToAno(String srcKey, String desKey, int sca, String sPin, String primaryAccount);
/**
* 用一把DEK密钥加密数据, 报文总长度不大于8192
*
* @param alg 加密算法
* @param DEK DEK密钥
* @param infoData 数据
* @param vector 初始向量数据 可选项,当加密模式为CBC,CFB或OFB时才显示此项
* @param disperseAlg 分散算法
* @return 密文数据
*/
byte[] SYD_Encrypt_Data(int alg, String DEK, byte[] infoData, byte[] vector, int disperseAlg, byte[] factor);
/**
* 用DEK密钥解密数据, 报文总长度不大于8192
*
* @param alg 解密算法
* @param DEK DEK密钥
* @param infoData 数据密文
* @param vector 初始向量数据 可选项,当加密模式为CBC,CFB或OFB时才显示此项
* @param disperseAlg 分散算法
* @return 解密后的明文数据
*/
byte[] SYD_Decrypt_Data(int alg, String DEK, byte[] infoData, byte[] vector, int disperseAlg, byte[] factor);
/**
* 对于给定的数据生成一个MAC
*
* @param key LMK对(16-17)下加密的TAK
* @param infoData 生成MAC的数据
* @param IV
* @param disperseNum 指定对根密钥分散的次数(1-3次)
* @param disperseAlg 分散算法
* @return 所计算出的MAC
*/
byte[] SYD_MAC_Data(String key, String infoData, byte[] factor, String IV, int disperseNum, int disperseAlg);
/**
* 对称加密数据
* @param key 索引地址,指示用户密钥存储区的27位地址
* @param intPutData 消息数据
* @return
* iv: IV 数据域
* msg_all: 消息数据
*/
public String SYMEncrytByKeyIndex( String key, String intPutData);
/**
* 对称解密数据
* @param key 索引地址,指示用户密钥存储区的27位地址
* @param intPutData 消息数据
* @return 消息数据
*/
public String SYMDecrytByKeyIndex(String key,String intPutData);
//通过索引读取对称秘钥
RetWrap readKey(String index);
}
@@ -0,0 +1,31 @@
package com.sunyard.inf.customize;
/**
* 上清所数字信封类接口
*/
public interface Syd4DigitalEnvelope {
/**
* 产生对称密钥,通过清算所公钥证书加密生成数字信封。
* 上清所
* @param pcDnEN: 清算所的公钥证书
* @param pcDnSign:会员的私钥证书
* @param pcData: 明文数据。
* @return pcSignData: 签名数字信封
*/
public String SYD_SignDigitalEnvelope (String pcDnEN, String pcDnSign, byte[] pcData);
/**
* 利用清算所公钥证书对签名数据进行验签。接收用会员的私钥证书解密数字信封,还原原文。
* 上清所
* @param pcDnDe: 会员的私钥证书
* @param pcDnVerify: 清算所公钥证书
* @param pcSignData: 签名数字信封数据。
* @return pcData:原数据
*/
public byte[] SYD_VerifyDigitalEnveloe(String pcDnDe, String pcDnVerify, String pcSignData );
}
@@ -117,9 +117,16 @@ public interface SydHAApi {
* @param nOrgDataType 签名数据类型,SydApi.DATA_ORIGIN(1) 原始数据 SydApi.DATA_HASH(0) : hash 后的类型
* @param publicKey 公钥串,DER编码,HEX格式
* @param orgData 待签名的原始数据,“签名数据类型”为 0 时:HASH 值。“签名数据类型”为 1 时:要签名的信息
* @param base64Sign 签名数据 (DER 编码 + Base64 编码)
* @param sign S+R
* @return 验签是否通过
*/
public boolean SM2Verify(
int nOrgDataType,
byte[] publicKey,
byte[] orgData,
byte[] sign
);
public boolean SM2Verify(
int nOrgDataType,
byte[] publicKey,
@@ -1,185 +0,0 @@
package com.sunyard.inf.customize;
import com.sunyard.SydApiException;
import com.sunyard.cert.X509;
import com.sunyard.proto.Packet;
import com.sunyard.proto.PacketSection;
import com.sunyard.proto.Util;
import com.sunyard.trans.PacketSN;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.proto.Proto8003;
import racal.sunyard.main.proto.Proto8004;
import racal.sunyard.main.proto.Proto8012;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class SydSDNXApiImpl extends SydApi4j implements SydSDNXApi {
public String nakedSign(byte[] orgData, String sCertDN) {
Proto8003 proto = new Proto8003(); //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("signatureDataType$option", 1);
data.put("DN", dn);
data.put("data", 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 Util.encodeBase64(((PacketSection) ret.get("signature")).getBytes());
//return ((PacketSection) ret.get("signature")).getBytes();
}
@Override
public boolean SYD_NakedVerify(byte[] orgData, String sign, String organizationNum) {
Proto8004 proto = new Proto8004(); //pset.getProtocolReqRender("75");
byte[] dn = new byte[256];
byte[] s = null;
// 填充数据
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("signatureDataType$option", 2);
data.put("organizationNum", organizationNum);
data.put("data", orgData);
data.put("signature", Util.decodeBase64(sign));
data.put("returnSign$option", 0);
// 渲染发送
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]))) {
throw new SydApiException(error.getInfo(), error.autoInt());
}
return true;
}
@Override
public X509 SYD_Get_X509_CertInfo_HA(String bNumber, byte[] orgData, String sign) {
Proto8012 proto = new Proto8012(); //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("originData", orgData);
data.put("signData", sign.getBytes());
data.put("flag$option", 2);
data.put("organizationNum", bNumber);
// 渲染发送
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]))) {
throw new SydApiException(error.getInfo(), error.autoInt());
}
PacketSection info = (PacketSection) ret.get("info");
byte[] pCertInfo = info.getBytes();
// X509 cinfo = new X509();
// cinfo.setIssuer(Util.toCleanString(pCertInfo, 0, 257));
// cinfo.setSerialNumber(Util.toCleanString(pCertInfo, 257, 65));
// cinfo.setSubject(Util.toCleanString(pCertInfo, 257 + 65, 257));
// cinfo.setNotBefore(Util.toCleanString(pCertInfo, 257 + 65 + 257, 15));
// cinfo.setNotAfter(Util.toCleanString(pCertInfo, 257 + 65 + 257 + 15, 15));
// byte[] blen = new byte[]{pCertInfo[257 + 65 + 257 + 15 + 15], pCertInfo[257 + 65 + 257 + 15 + 16]};
// int len = Util.b2i(blen);
// byte[] pem = new byte[len];
// System.arraycopy(pCertInfo, 257 + 65 + 257 + 15 + 17, pem, 0, len);
// String pp = new String(pem);
// 解析证书
return GetX509CertInfo(new String(pCertInfo));
}
}
@@ -0,0 +1,212 @@
package com.sunyard.inf.sva;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
import java.io.UnsupportedEncodingException;
/**
* 带原文的签名验签
*/
public interface SydAttachedSVApi {
/**
* sm2私钥签名
* 用户id默认为1234567812345678
* 签名结果R/S序列串先进行der编码,再进行base64编码
*
* @param flag 私钥标志位,当为1时第二个参数传入存储私钥的索引,当为0时第二个参数传入私钥
* @param privateKey 当私钥标志位为1时传入存储私钥的索引,当为0时传入私钥
* @param publicKey 公钥
* @param orgData 要签名的信息
* @return 签名结果
*/
byte[] SM2SignC(int flag, String privateKey, byte[] publicKey, byte[] orgData);
byte[] SM2SignC(int flag, String pUserID, String privateKey, byte[] publicKey, byte[] orgData);
/**
* SM2 私钥签名
* @param pUserID 使用者的 ID,最大长度为 16 位数字,右对齐。
* @param certNo 证书号
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据
* @param publicKey 公钥的 DER 编码
* @param orgData 原始数据
* @return 签名的 base64 编码
*/
String SM2SignC(
String pUserID,
String certNo,
int nOrgDataType,
byte[] publicKey,
byte[] orgData
);
/**
* RSA 私钥签名
* @param HashMark 哈希标识 指示用于哈希证书数据的哈希算法的标识。0: SHA1 1: SHA256 2: MD5。
* @param privateKeyTag 私钥标记 指示私钥位置的标记。数字为存储私钥的索引,除了全9表示使用由命令中提供的密钥。
* 27位的索引号:16位机构号+3位密钥类型+8位密钥索引号
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据
* @param orgData 原始数据
* @return 签名的 base64 编码
*/
byte[] RSASignC(
String privateKeyTag,
int HashMark,
int nOrgDataType,
byte[] orgData);
byte[] RSASign(
String privateKey,
int HashMark,
int nOrgDataType,
byte[] orgData);
/**
* 采用 RSA 算法,用指定的公钥对指定的原始数据进行数字签名验证。
* @param HashMark 哈希标识
* @param nOrgDataType 签名方式
* @param publicKey 公钥
* @param orgData 原始数据
* @param sign base64 格式的签名
* @return true 验签通过 false 验签失败
*/
boolean RSAVerify(
int HashMark,
int nOrgDataType,
byte[] publicKey,
byte[] orgData,
byte[] sign);
/**
* sm2验签
* 用户id默认为1234567812345678
*
* @param publicKey 公钥的 DER 编码
* @param orgData 要签名的信息
* @param base64Sign 计算的签名,签名结果R/S序列串先进行der编码,再进行base64编码后的结果
* @return true 验签成功,false 验签失败
*/
boolean SM2Verify(byte[] publicKey, byte[] orgData, String base64Sign);
/**
* 采用 SM2 算法,用指定的公钥对指定的原始数据进行数字签名验证。
* @param certNo id 用于计算SM3-HASH
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据,用1.2.3章节限定符亦可
* @param publicKey 公钥
* @param orgData 原始数据
* @param sign base64 格式的签名
* @return true 验签通过 false 验签失败
*/
boolean SM2Verify(
String certNo,
int nOrgDataType,
byte[] publicKey,
byte[] orgData,
byte[] sign
);
/**
* SM2 私钥签名
* @param certNo 证书号
* @param orgData 原始数据
* @return 签名的 base64 编码
*/
String SM2SignCustomized(
String certNo,
byte[] orgData
);
/**
* 采用 SM2 算法,用指定的公钥对指定的原始数据进行数字签名验证。
* @param certNo 证书号
* @param orgData 原始数据
* @param sign base64 格式的签名
* @return true 验签通过 false 验签失败
*/
boolean SM2VerifyCustomized(
String certNo,
byte[] orgData,
String sign
);
/**
* 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制带公钥证书的数字签名(遵循 PKCS#7)。
*
* @param orgData 待签名数据
* @param sCertDN 证书DN
* @return
* 符合PKCS7标准的签名结果
*/
String attachedSign(byte[] orgData, String sCertDN) throws UnsupportedEncodingException;
byte[] attachedSignC(byte[] orgData, String sCertDN);
/**
* 人行项目需要需要支持RSA
* 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制带公钥证书的数字签名(遵循 PKCS#7)。
*
* @param orgData 待签名数据
* @param sCertDN 证书DN
* @return
* 符合PKCS7标准的签名结果
*/
String attachedSignRSA(int rFlag,byte[] orgData, String sCertDN) throws UnsupportedEncodingException;
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return true 验签通过 false 验签失败
*/
boolean attachedVerify(String sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return true 验签通过 false 验签失败
*/
boolean attachedVerifyRSA(int rFlag,String sign);
boolean attachedVerify(byte[] sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return 成功返回签名的原数据,失败则报错
*/
byte[] attachedVerifyRD(byte[] sign);
byte[] attachedVerifyRD(String sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return
* 若发送报文返回证书信息标志位为0,则返回已签名数据,
* 若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据
*/
X509 attachedVerifyAndGetX509(byte[] sign);
X509 attachedVerifyAndGetX509(String sign);
/**
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
*
* @param sign 已签名数据
* @return
* 若发送报文返回证书信息标志位为0,则返回已签名数据,
* 若发送报文返回证书信息标志位为1,则返回CERT_INFO结构的证书数据
*/
RetWrap attachedVerifyAndGetAll(byte[] sign);
}
@@ -0,0 +1,178 @@
package com.sunyard.inf.sva;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
/**
* 不带原文的签名验签
*/
public interface SydDetachedSVApi {
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
public boolean SYD_DetachedVerify(
byte[] orgData,
String sign);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String SYD_DetachedSign(
byte[] orgData,
String sCertDN
);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 待签名的原始数据将在接口内部进行 sm3 ,然后做 Detach 签名
* @param orgData 待签名的原始数据
* @param publicKey sm3 hash 所用的公钥
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String sm3AndDetachedSign(
byte[] orgData,
String publicKey,
String sCertDN
);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 原始数据将在接口内部进行 sm3 ,然后做 Detach 验签
* @param orgData 待签名的原始数据
* @param publicKey sm3 hash 所用的公钥
* @param sign 签名数据
* @return 验签是否通过
*/
public boolean sm3AndDetachedVerify(
byte[] orgData,
String publicKey,
String sign);
/**
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 待签名的原始数据将在接口内部进行不带公钥的 sm3 ,然后做 Detach 签名
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
String sm3WithoutPKDetachedSign(byte[] orgData, String sCertDN);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 原始数据将在接口内部进行无公钥的 sm3 ,然后做 Detach 验签
*
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean sm3WithoutPKDetachedVerify(byte[] orgData, String sign);
/**
*
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 数据模式,输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 输入的数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public String detachedSign(
int dataType,
byte[] orgData,
String sCertDN
);
/**
* 带公钥证书与签名属性的数字签名(遵循 PKCS#7)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为数据
* @param keyTag 密钥对应的索引号
* @return 签名的 DER 编码
*/
public byte[] detachedSign(
int dataType,
byte[] orgData,
int keyTag
);
/**
* 带公钥证书的PKCS#7数字签名(序列号)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为要签名的信息
* @param certificateNo X509证书序号
* @return 符合PKCS7标准的签名结果
*/
public String detachedSignbysn(
int dataType,
byte[] orgData,
String certificateNo);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 验签是否通过
*/
boolean detachedVerify(
int dataType,
byte[] orgData,
String sign);
/**
* 带公钥证书与签名属性的数字签名验签(遵循 PKCS#7)
* @param dataType 数据类型:0,hash 模式,1为非hash模式
* @param orgData 当为hash模式时,值为hash值,当为非hash模式时,值为数据
* @param sign 已签名数据
* @return 是否正确
*/
boolean detachedVerify(
int dataType,
byte[] orgData,
byte[] sign);
/**
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)返回证书信息
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
*
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @return 证书
*/
X509 detachedVerifyAndGetX509(int dataType,
byte[] orgData,
String sign);
/**
* 计算SM3散列值
* @param packSn 消息块号,0=仅一块,1=第一块,2=中间块,3=最后块
* @param userId 用户 ID,只对“消息块号”为 0、1 时有效
* @param publicKey 公钥的 DER 编码
* @param msg 二进制的消息块
* @param filterData 过渡消息数据,只对“消息块号”为 2、3 时有效
* @return
* filterData: 过渡消息数据,只对“消息块号”为 2、1 时有效
* hash: hash
*/
RetWrap SM3Hash(int packSn, String userId, byte[] publicKey, byte[] msg, byte[] filterData);
}
@@ -0,0 +1,32 @@
package com.sunyard.inf.sva;
/**
* 不经过 CA 授信
* 直接使用公私钥对签名验签
*/
public interface SydNakedSVApi {
/**
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
* @param orgData 待签名的原始数据
* @param sCertDN 签名者证书 DN
* @return 签名数据
*/
public byte[] SYD_NakedSign(
byte[] orgData,
String sCertDN
);
/**
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
* @param orgData 待签名的原始数据
* @param sign 签名数据
* @param sCertDN 签名者证书 DN
* @return 验签是否通过
*/
public boolean SYD_NakedVerify(
byte[] orgData,
byte[] sign,
String sCertDN
);
}
@@ -0,0 +1,5 @@
package com.sunyard.log;
public interface ILogFactory {
ILogger getLogger(Class cls);
}
@@ -0,0 +1,11 @@
package com.sunyard.log;
public interface ILogger {
public int getCurrentLogLevel();
public void error(String msg, Object ...params);
public void info(String msg, Object ...params);
public void debug(String msg, Object ...params);
}
@@ -0,0 +1,118 @@
package com.sunyard.log;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class SydLogFactory implements ILogFactory {
// 日期格式
private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
// 日志目录
public static String pcLogPath = "./sydapi-logs/";
// 日志名
public static final String logName = "sydapi-log";
// 日志级别
public static int iLogLevel = 0;
// 日志队列
private static ConcurrentLinkedQueue<SydLogInfo> queue = new ConcurrentLinkedQueue<SydLogInfo>();
// 调试标记
public static boolean debug = false;
// 后台打印进程
private static Executor executor = Executors.newSingleThreadExecutor();
static {
executor.execute(new Runnable() {
@Override
public void run() {
String logFileName = "";
FileOutputStream logFos = null;
while (true) {
try {
if (queue.isEmpty()) {
// 释放 CPU
Thread.sleep(500);
continue;
}
// 有日志
// 确认日期
String mayLogFileName = String.format("%s_%s.log", logName, format.format( new Date()));
if ( ! logFileName.equals( mayLogFileName ) ) {
logFileName = mayLogFileName;
if ( null != logFos ) {
logFos.flush();
logFos.close();
}
File folder = new File( pcLogPath );
if ( ! folder.exists() ) {
folder.mkdirs();
}
File f = new File( pcLogPath, logFileName );
if ( ! f.exists() ) {
f.createNewFile();
}
logFos = new FileOutputStream( f , true);
}
while (!queue.isEmpty()) {
SydLogInfo info = queue.poll();
logFos.write(String.format("[%d:%s <%s-%d>] %s\r\n",
info.getLevel(),
format.format( new Date(info.getDatatime()) ),
info.getTname(),
info.getTid(),
info.getMsg()
).getBytes()
);
}
logFos.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeFileOutputStream(logFos);
logFileName = "";
}
}
}
});
}
private static void closeFileOutputStream(FileOutputStream fos){
if ( null != fos ) {
try {
fos.flush();
}catch (Exception e) {
//pass
}
try {
fos.close();
}catch (Exception e) {
//pass
}
}
}
private SydLogFactory() {
}
@Override
public ILogger getLogger(Class cls) {
return new SydLogger(queue);
}
}
@@ -0,0 +1,44 @@
package com.sunyard.log;
public class SydLogInfo {
private int level;
private long datatime;
private String tname;
private long tid;
private String msg;
private Object[] objects;
public SydLogInfo(int level, String msg, Object[] objects) {
this.level = level;
this.msg = msg;
this.objects = objects;
this.datatime = System.currentTimeMillis();
this.tname = Thread.currentThread().getName();
this.tid = Thread.currentThread().getId();
}
public int getLevel() {
return level;
}
public long getDatatime() {
return datatime;
}
public String getTname() {
return tname;
}
public long getTid() {
return tid;
}
public String getMsg() {
return msg;
}
public Object[] getObjects() {
return objects;
}
}
@@ -0,0 +1,42 @@
package com.sunyard.log;
import java.util.concurrent.ConcurrentLinkedQueue;
public class SydLogger implements ILogger{
private ConcurrentLinkedQueue<SydLogInfo> queue;
SydLogger(ConcurrentLinkedQueue<SydLogInfo> queue) {
this.queue = queue;
}
public void debug(String msg, Object... params) {
if (SydLogFactory.iLogLevel == 3) {
this.queue.add(new SydLogInfo(3, msg, params));
} else {
return;
}
}
public void info(String msg, Object... params) {
if (SydLogFactory.iLogLevel >= 2) {
this.queue.add(new SydLogInfo(2, msg, params));
} else {
return;
}
}
public void error(String msg, Object... params) {
if (SydLogFactory.iLogLevel >= 1) {
this.queue.add(new SydLogInfo(1, msg, params));
} else {
return;
}
}
@Override
public int getCurrentLogLevel() {
return SydLogFactory.iLogLevel;
}
}
@@ -0,0 +1,63 @@
package com.sunyard.pool;
/**
* 到加密机的链接信息
*/
public class HsmLinkInfo {
private String pcIp;
private int iPort;
private int iConnectTimeOut;
private int iDealTimeOut;
public HsmLinkInfo(String pcIp, int iPort, int iConnectTimeOut, int iDealTimeOut) {
this.pcIp = pcIp;
this.iPort = iPort;
this.iConnectTimeOut = iConnectTimeOut;
this.iDealTimeOut = iDealTimeOut;
}
public static HsmLinkInfo[] mutiHsmLinkInfo(String[] pcIpList, int[] iPortList, int iConnectTimeOut, int iAllDealTimeOut) {
if (null == pcIpList &&
null == iPortList &&
pcIpList.length != iPortList.length) {
throw new IllegalArgumentException("入参错误");
}
if ( iAllDealTimeOut < pcIpList.length) {
throw new IllegalArgumentException("入参错误");
}
// 交易时间进行处理
int iDealTimeOut = iAllDealTimeOut / pcIpList.length;
HsmLinkInfo[]hsms = new HsmLinkInfo[ pcIpList.length ];
for ( int i = 0 ; i < pcIpList.length ; i++ ) {
hsms[ i ] = new HsmLinkInfo( pcIpList[i], iPortList[i], iConnectTimeOut, iDealTimeOut );
}
return hsms;
}
public String getPcIp() {
return pcIp;
}
public int getiPort() {
return iPort;
}
public int getiConnectTimeOut() {
return iConnectTimeOut;
}
public int getiDealTimeOut() {
return iDealTimeOut;
}
}
@@ -0,0 +1,28 @@
package com.sunyard.pool;
public class ObjectInPool<T> {
private T object;
private long lasUseAt = System.currentTimeMillis();
public ObjectInPool(T object) {
this.object = object;
}
public T getObjectForCheck() {
return this.object;
}
public void updateLastUseTime(){
this.lasUseAt = System.currentTimeMillis();
}
public T getObject() {
this.lasUseAt = System.currentTimeMillis();
return this.object;
}
public long getLasUseAt() {
return this.lasUseAt;
}
}
@@ -0,0 +1,26 @@
package com.sunyard.pool;
public class PoolConfig {
// 最大空闲时间
private long maxIdle = 5 * 60 *1000; // 5 分钟
// 最大无用时间
private long maxUseless = 30 * 60 * 1000; // 30 分钟
public long getMaxIdle() {
return maxIdle;
}
public void setMaxIdle(long maxIdle) {
this.maxIdle = maxIdle;
}
public long getMaxUseless() {
return maxUseless;
}
public void setMaxUseless(long maxUseless) {
this.maxUseless = maxUseless;
}
}
@@ -0,0 +1,84 @@
package com.sunyard.pool;
import com.sunyard.SydApi;
import com.sunyard.SydApiException;
import com.sunyard.proxy.ProxyInvocationHandler;
import racal.sunyard.main.SydApi4j;
public class SydApiPool extends ThreadBasedConnectPool<SydApi> {
private HsmLinkInfo[] linkInfos;
public SydApiPool(HsmLinkInfo[] linkInfos) {
this.linkInfos = linkInfos;
}
protected SydApi initialValue() {
SydApi4j[] apis = new SydApi4j[this.linkInfos.length];
boolean connected = false;
for(int i = 0; i < apis.length; ++i) {
HsmLinkInfo info = this.linkInfos[i];
try {
apis[i] = (SydApi4j)(new SydApi4j()).connect(info.getPcIp(), info.getiPort(), (String)null, info.getiConnectTimeOut(), info.getiDealTimeOut());
connected = true;
} catch (Exception var6) {
}
}
if (!connected) {
throw new SydApiException("连接错误", -1);
} else {
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(apis, this.linkInfos, false);
return proxyInvocationHandler.getProxy();
}
}
public boolean check(SydApi s) {
boolean ret = super.check(s);
if (!ret) {
return false;
} else {
ProxyInvocationHandler o = (ProxyInvocationHandler)s.getBindObject();
try {
SydApi4j[] hsms = o.getApis();
boolean canUse = false;
int length = hsms.length;
for(int i = 0; i < length; ++i) {
if (null != hsms[i]) {
try {
synchronized(hsms[i]) {
hsms[i].GenerateRandom(1);
canUse = true;
}
} catch (Exception var12) {
hsms[i] = null;
}
} else {
HsmLinkInfo[] infos = o.getApisInfos();
HsmLinkInfo info = infos[i];
try {
hsms[i] = (SydApi4j)(new SydApi4j()).connect(info.getPcIp(), info.getiPort(), (String)null, info.getiConnectTimeOut(), info.getiDealTimeOut());
canUse = true;
} catch (Exception e) {
}
}
}
return canUse;
} catch (Exception e) {
return false;
}
}
}
protected void free(SydApi o) {
if (null != o) {
o.disconnect();
}
}
}
@@ -0,0 +1,125 @@
package com.sunyard.pool;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadBasedConnectPool<T> {
// ThreadLocal
private final Map<Thread, ObjectInPool<T>> map = new HashMap<Thread, ObjectInPool<T>>();
// 守护
private final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(1);
// 配置
private PoolConfig config;
public ThreadBasedConnectPool(final PoolConfig config) {
this.config = config;
threadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// 检测和回收逻辑
Iterator<Map.Entry<Thread, ObjectInPool<T>>> it = map.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Thread, ObjectInPool<T>> entry = it.next();
ObjectInPool<T> oip = entry.getValue();
if (System.currentTimeMillis() - oip.getLasUseAt() < config.getMaxIdle()) {
// 空闲时间不足,免检。
continue;
}
if (System.currentTimeMillis() - oip.getLasUseAt() > config.getMaxUseless()) {
// 长时间未使用,回收链接
it.remove();
try {
free(oip.getObject());
} catch (Exception e) {
}
continue;
}
boolean checkPass = false;
try {
checkPass = check(entry.getValue().getObjectForCheck());
} catch (Exception e) {
checkPass = false;
}
finally {
}
if ( ! checkPass) {
// 检查未通过
it.remove();
try {
free(oip.getObject());
} catch (Exception e) {
}
continue;
}
}
}
}, config.getMaxIdle(), config.getMaxIdle(), TimeUnit.MILLISECONDS);
}
public ThreadBasedConnectPool() {
this(new PoolConfig());
}
// 继承 初始化
protected T initialValue() {
return null;
}
// 保活接口
protected boolean check(T o) {
return null != o;
}
// 释放
protected void free(T o) {
}
// 获取
public T get() {
ObjectInPool<T> o = map.get(Thread.currentThread());
if (null != o) {
return o.getObject();
}
return setInitialValue();
}
// 设置
public void set(T o) {
map.put(Thread.currentThread(), new ObjectInPool<T>(o));
}
// 清除
public void remove() {
map.remove(Thread.currentThread());
}
protected void afterInit(ObjectInPool oip, T value ){
}
private T setInitialValue() {
T value = initialValue();
ObjectInPool opi = new ObjectInPool<T>(value);
map.put(Thread.currentThread(), opi);
afterInit( opi , value);
return value;
}
}
@@ -0,0 +1,165 @@
package com.sunyard.proxy;
import com.sunyard.SydApi;
import com.sunyard.SydApiException;
import com.sunyard.log.ILogFactory;
import com.sunyard.log.ILogger;
import com.sunyard.pool.HsmLinkInfo;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiMuti;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ProxyInvocationHandler implements InvocationHandler {
private static Map<String, SydApiException> innerFuncs = new HashMap<String, SydApiException>();
static {
innerFuncs.put("connect", new SydApiException("集群连接模式,不需要该连接", 0));
}
private SydApi4j[] apis;
private HsmLinkInfo[] apisInfos;
private boolean isShortLinkMode = true;
public ProxyInvocationHandler(SydApi4j[] apis) {
this.apis = apis;
}
public ProxyInvocationHandler(SydApi4j[] apis, HsmLinkInfo[] info, boolean isShortLinkMode) {
this.apis = apis;
this.apisInfos = info;
this.isShortLinkMode = isShortLinkMode;
}
public SydApi4j[] getApis() {
return apis;
}
public HsmLinkInfo[] getApisInfos() {
return apisInfos;
}
public SydApi getProxy() {
SydApi api = (SydApi) Proxy.newProxyInstance(
SydApi4j.class.getClassLoader(),
new Class[]{SydApi.class},
this
);
api.setBindObject( this );
return api;
}
public void disconnect() {
if (null != apis && isShortLinkMode) {
for (SydApi4j api4j : this.apis) {
try {
if (null != api4j) {
api4j.disconnect();
}
} catch (Exception e) {
// pass
}
}
}
}
//处理代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
SydApiException le = null;
if ("disconnect".equals(method.getName())) {
this.disconnect();
}
// 屏蔽部分非业务接口
if ("connect".equals(method.getName())) {
throw new RuntimeException("不允许使用此接口");
}
if (innerFuncs.containsKey(method.getName())) {
innerFuncs.get(method.getName());
}
if ("deleteCert".equals(method.getName()) || "SYD_Get_X509_CertInfo_HA".equals(method.getName())) {
for (SydApi4j api : apis) {
if (null == api) {
if ("deleteCert".equals(method.getName())) {
throw new SydApiException("删除失败",56307);
} else {
throw new SydApiException("导入失败",56300);
}
}
try {
Object ret = method.invoke(api, args);
if ( ret instanceof Boolean ) {
if ( ! ( Boolean ) ret ) {
throw new RuntimeException("结果错误");
}
}
} catch (SydApiException e) {
if ("deleteCert".equals(method.getName())) {
throw new SydApiException("删除失败",56307);
} else {
throw new SydApiException("导入失败",56300);
}
}
}
}
for (SydApi4j api : apis) {
if (null == api) {
continue;
}
if ( isShortLinkMode ) {
try {
return method.invoke(api, args);
} catch (SydApiException e) {
le = e;
if (e.getRetCode() < 0) {
continue;
}
throw e;
}
} else {
synchronized (api) {
try {
return method.invoke(api, args);
} catch (SydApiException e) {
le = e;
if (e.getRetCode() < 0) {
continue;
}
throw e;
} catch ( Exception e ) {
ILogFactory factory = SydApi4j.getLogFactory();
if ( null != factory ) {
ILogger logger = factory.getLogger(ProxyInvocationHandler.class);
logger.error( "调用方法 {} 失败", method.getName() );
}
throw e;
}
}
}
}
throw le;
}
}
@@ -0,0 +1,112 @@
package com.sunyard.snmp;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseListener;
import org.snmp4j.mp.*;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
public class SnmpTrapSender implements AutoCloseable{
private Snmp snmp;
// 配置参数
private String ip;
private int port;
private String enterpriseOid;
private String community;
private int version;
public SnmpTrapSender(Map<String, String> map) throws Exception {
loadConfig(map);
initializeSNMP();
}
public void loadConfig(Map<String, String> map) {
ip = map.getOrDefault("snmp.target.ip", null);
port = Integer.parseInt(map.getOrDefault("snmp.target.port", "162"));
enterpriseOid = map.getOrDefault("enterprise.oid", null);
community = map.getOrDefault("snmp.community", "public");
version = Integer.parseInt(map.getOrDefault("snmp.version", "1"));
}
private void initializeSNMP() throws Exception {
TransportMapping<?> transport = new DefaultUdpTransportMapping();
snmp = new Snmp(transport);
snmp.listen();
}
public ResponseEvent sendTrap(String message, int severity) throws Exception {
ResponseEvent event = null;
switch (version) {
case SnmpConstants.version1:
event = sendV1Trap(message, severity);
break;
case SnmpConstants.version2c:
event = sendV2Trap(message, severity);
break;
default:
throw new IllegalArgumentException("不支持的SNMP版本");
}
return event;
}
private ResponseEvent sendV1Trap(String message, int severity) throws Exception {
CommunityTarget target = createCommunityTarget(SnmpConstants.version1);
PDUv1 pdu = new PDUv1();
configureCommonTrap(pdu, message, severity);
pdu.setGenericTrap(PDUv1.ENTERPRISE_SPECIFIC);
return snmp.send(pdu, target);
}
private ResponseEvent sendV2Trap(String message, int severity) throws Exception {
CommunityTarget target = createCommunityTarget(SnmpConstants.version2c);
PDU pdu = new PDU();
configureCommonTrap(pdu, message, severity);
pdu.setType(PDU.TRAP);
return snmp.send(pdu, target);
}
private void configureCommonTrap(PDU pdu, String message, int severity) {
pdu.add(new VariableBinding(SnmpConstants.sysUpTime,
new TimeTicks(System.currentTimeMillis()/1000)));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID,
new OID(enterpriseOid + ".1.1")));
byte[] msg = new byte[10];
try {
msg = message.getBytes("GBK");
} catch (Exception e) {
System.out.println("编码错误");
}
pdu.add(new VariableBinding(new OID(enterpriseOid + ".2.1"),
new OctetString(msg)));
pdu.add(new VariableBinding(new OID(enterpriseOid + ".2.2"),
new Integer32(severity)));
}
private CommunityTarget createCommunityTarget(int version) {
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString(community));
target.setAddress(GenericAddress.parse("udp:"+ip+"/"+port));
target.setVersion(version);
target.setTimeout(5000);
target.setRetries(3);
return target;
}
@Override
public void close() throws Exception {
if (snmp != null) {
snmp.close();
snmp = null;
}
}
}
@@ -0,0 +1,121 @@
package com.sunyard.task;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
public class AsyncTaskExecutor {
private final ExecutorService taskExecutor;
private final ScheduledExecutorService retryScheduler;
public AsyncTaskExecutor(int taskThreads, int retryThreads) {
this.taskExecutor = Executors.newFixedThreadPool(taskThreads);
this.retryScheduler = Executors.newScheduledThreadPool(retryThreads);
}
// 默认配置构造函数
public AsyncTaskExecutor() {
this(2, 2);
}
public List<TaskOutcome<String>> execBatchTasks(List<TaskContext<String>> taskContexts) {
// 转换每个Future为明确的TaskOutcome类型
List<CompletableFuture<TaskOutcome<String>>> futures = taskContexts.stream()
.map(task ->
retryWithDelay(task)
.<TaskOutcome<String>>handle((result, ex) -> {
if (ex != null) {
// 提取原始异常
Throwable cause = ex instanceof CompletionException ? ex.getCause() : ex;
return new TaskOutcome<>(task, cause);
} else {
return new TaskOutcome<>(task, result);
}
})
)
.collect(Collectors.toList());
// 等待所有任务完成
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
futures.toArray(new CompletableFuture[0])
);
// 收集处理结果
return allFutures.thenApply(v ->
futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList())
).join();
}
/**
* 带延迟的重试逻辑
*/
private <T> CompletableFuture<T> retryWithDelay(TaskContext<T> context) {
return CompletableFuture.supplyAsync(context.getTask(), taskExecutor)
.handleAsync((result, ex) -> {
if (ex == null) {
return CompletableFuture.completedFuture(result);
} else {
return handleRetry(context, ex);
}
}, taskExecutor)
.thenCompose(f -> f);
}
/**
* 处理重试逻辑
*/
private <T> CompletableFuture<T> handleRetry(TaskContext<T> context, Throwable ex) {
if (context.canRetry()) {
context.decreaseRetry();
// System.out.printf("[重试调度] ID: %s| IP:%s | 延迟: %ss | 剩余重试: %d | 错误: %s%n",
// context.getTaskId(),
// context.getAddress(),
// context.getRetryDelay().getSeconds(),
// context.getRetriesLeft(),
// ex.getCause().getMessage());
// 创建延迟重试的Future
CompletableFuture<T> delayedRetry = new CompletableFuture<>();
retryScheduler.schedule(() -> {
retryWithDelay(context).whenComplete((retryResult, retryEx) -> {
if (retryEx != null) {
delayedRetry.completeExceptionally(retryEx);
} else {
delayedRetry.complete(retryResult);
}
});
}, context.getRetryDelay().toMillis(), TimeUnit.MILLISECONDS);
return delayedRetry;
} else {
// 重试耗尽,传递原始异常
CompletableFuture<T> failed = new CompletableFuture<>();
failed.completeExceptionally(ex);
return failed;
}
}
/**
* 关闭线程池
*/
public void shutdown() {
taskExecutor.shutdown();
retryScheduler.shutdown();
try {
if (!taskExecutor.awaitTermination(1, TimeUnit.SECONDS)) {
taskExecutor.shutdownNow();
}
if (!retryScheduler.awaitTermination(1, TimeUnit.SECONDS)) {
retryScheduler.shutdownNow();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
@@ -0,0 +1,50 @@
package com.sunyard.task;
import java.time.Duration;
import java.util.UUID;
import java.util.function.Supplier;
public class TaskContext<T> {
private final String taskId; // 唯一任务ID
private final Supplier<T> task; // 原始任务逻辑
private int retriesLeft; // 剩余重试次数
private final Duration retryDelay; // 重试延迟
private final String address;
public TaskContext(Supplier<T> task, int maxRetries, Duration retryDelay, String address) {
this.taskId = UUID.randomUUID().toString();
this.task = task;
this.retriesLeft = maxRetries;
this.retryDelay = retryDelay;
this.address = address;
}
public String getAddress() {
return address;
}
public String getTaskId() {
return taskId;
}
public Supplier<T> getTask() {
return task;
}
public int getRetriesLeft() {
return retriesLeft;
}
public boolean canRetry() {
return retriesLeft > 0;
}
public void decreaseRetry() {
retriesLeft--;
}
public Duration getRetryDelay() {
return retryDelay;
}
}
@@ -0,0 +1,35 @@
package com.sunyard.task;
public class TaskOutcome<T> {
private final TaskContext<T> context;
private final T result;
private final Throwable error;
public TaskOutcome(TaskContext<T> context, T result) {
this.context = context;
this.result = result;
this.error = null;
}
public TaskOutcome(TaskContext<T> context, Throwable error) {
this.context = context;
this.result = null;
this.error = error;
}
public boolean isSuccess() {
return error == null;
}
public TaskContext<T> getContext() {
return context;
}
public T getResult() {
return result;
}
public Throwable getError() {
return error;
}
}
@@ -0,0 +1,72 @@
package com.sunyard.util;
import cn.hutool.core.bean.BeanUtil;
import com.sunyard.RetWrap;
import com.sunyard.proto.R;
import com.sunyard.proto.Util;
import org.bouncycastle.asn1.*;
import java.io.IOException;
public class ASN1Util {
public static byte[] alignSignDer(byte[] der) {
String base64 = Util.encodeBase64(der);
return SYMUtil.base64SignAsDerSign(base64);
}
public static RetWrap takeOutOriginDataFromPKCS7Sign(String sign) throws IOException {
RetWrap ret = new RetWrap();
ASN1Sequence seq = ASN1Sequence.getInstance( Util.decodeBase64( sign ) );
ASN1TaggedObject tag = (ASN1TaggedObject) seq.getObjectAt(1).toASN1Primitive();
ASN1Sequence seq2 = (ASN1Sequence) tag.getObject();
ASN1Sequence seq3 = null;
try {
seq3 = (ASN1Sequence) seq2.getObjectAt( 2 ).toASN1Primitive();
ASN1TaggedObject tag2 = (ASN1TaggedObject) seq3.getObjectAt( 1 );
DEROctetString o = (DEROctetString) tag2.getObject();
ret.put( "orgData", o.getOctets() );
} catch (Exception e) {
}
ASN1TaggedObject tag3 = (ASN1TaggedObject) seq2.getObjectAt(3).toASN1Primitive();
ASN1Sequence seq4 = (ASN1Sequence) tag3.getObject();
ret.put("cert", CertUtil.encodeBase64(seq4.getEncoded()));
ASN1Sequence seq5 = (ASN1Sequence) seq4.getObjectAt( 0 ).toASN1Primitive();
ASN1Sequence seq6 = (ASN1Sequence) seq5.getObjectAt( 6 ).toASN1Primitive();
DERBitString pk = (DERBitString) seq6.getObjectAt( 1 ).toASN1Primitive();
ret.put("pk", pk.getEncoded() );
ASN1Encodable[] elements = seq3.toArray();
ASN1Encodable[] elements2 = new ASN1Encodable[ elements.length - 1];
for ( int i = 0; i < elements.length -1 ; i++ ){
elements2[i] = elements[i];
}
BeanUtil.setProperty( seq3, "elements", elements2);
ret.put("sign", Util.encodeBase64(seq.getEncoded()) );
return ret;
}
public static String addOriginDataToPKCS7Sign( byte[] originData, String sign) throws IOException {
ASN1Sequence seq = ASN1Sequence.getInstance( Util.decodeBase64( sign ) );
ASN1TaggedObject tag = (ASN1TaggedObject) seq.getObjectAt(1).toASN1Primitive();
ASN1Sequence seq2 = (ASN1Sequence) tag.getObject();
ASN1Sequence seq3 = (ASN1Sequence) seq2.getObjectAt( 2 ).toASN1Primitive();
ASN1Encodable[] elements = seq3.toArray();
ASN1Encodable[] elements2 = new ASN1Encodable[ elements.length + 1];
for ( int i = 0; i < elements.length ; i++ ){
elements2[i] = elements[i];
}
elements2[ elements.length ] = new DERTaggedObject(true, 0, new DEROctetString( originData ));
BeanUtil.setProperty( seq3, "elements", elements2);
return Util.encodeBase64(seq.getEncoded());
}
}
@@ -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;
}
}
}
@@ -0,0 +1,44 @@
package com.sunyard.util;
import java.nio.ByteBuffer;
public class ByteBufferUtil {
public static ByteBuffer sliceRange(ByteBuffer source, int start, int length) {
// 保存原 buffer 的 position 和 limit
int oldPos = source.position();
int oldLimit = source.limit();
// 设置新的 position 和 limit 为目标区间
source.position(start);
source.limit(start + length);
// 创建共享视图(零拷贝)
ByteBuffer slice = source.slice();
// 恢复原 buffer 的 position 和 limit
source.position(oldPos);
source.limit(oldLimit);
return slice;
}
public static ByteBuffer sliceAndConsume(ByteBuffer source, int length) {
// 保存原 buffer 的 position 和 limit
int oldPos = source.position();
int oldLimit = source.limit();
// 设置新的 position 和 limit 为目标区间
int start = oldPos;
source.position(start);
source.limit(start + length);
// 创建共享视图(零拷贝)
ByteBuffer slice = source.slice();
// 恢复原 buffer 的 position 和 limit
source.position(oldPos + length);
source.limit(oldLimit);
return slice;
}
}
@@ -0,0 +1,174 @@
package com.sunyard.util;
import java.nio.ByteOrder;
/**
* 字节数组转换工具类,提供常见的基本类型与字节数组之间的互转功能。
* 默认采用大端字节序(高位在前),也支持通过参数指定字节序。
*
* @author YourName
*/
public final class BytesUtil {
private BytesUtil() {
// 私有构造方法,防止实例化
}
// ==================== 无符号 short 转字节数组 ====================
/**
* 将无符号 short 值(以 int 形式传入,范围 0 ~ 65535)转换为大端字节序的字节数组(2字节)。
*
* @param value 无符号 short 值(0 到 65535)
* @return 长度为 2 的字节数组,高位在前
* @throws IllegalArgumentException 如果 value 超出 0~65535 范围
*/
public static byte[] unsignedShortToBytes(int value) {
if (value < 0 || value > 0xFFFF) {
throw new IllegalArgumentException("Value out of range for unsigned short: " + value);
}
return new byte[]{
(byte) ((value >> 8) & 0xFF),
(byte) (value & 0xFF)
};
}
/**
* 将无符号 short 值(以 short 类型传入,自动按无符号处理)转换为大端字节序的字节数组(2字节)。
* 例如,传入 (short) 0x8001 会得到 { (byte)0x80, (byte)0x01 }。
*
* @param value short 类型,将按其二进制补码表示直接作为无符号值处理
* @return 长度为 2 的字节数组,高位在前
*/
public static byte[] unsignedShortToBytes(short value) {
// 将 short 转为无符号 int
int unsignedValue = value & 0xFFFF;
return unsignedShortToBytes(unsignedValue);
}
/**
* 将无符号 short 值(int 类型)转换为指定字节序的字节数组(2字节)。
*
* @param value 无符号 short 值(0 到 65535)
* @param byteOrder 字节序,ByteOrder.BIG_ENDIAN 或 ByteOrder.LITTLE_ENDIAN
* @return 长度为 2 的字节数组
* @throws IllegalArgumentException 如果 value 超出范围或 byteOrder 为 null
*/
public static byte[] unsignedShortToBytes(int value, ByteOrder byteOrder) {
if (byteOrder == null) {
throw new IllegalArgumentException("ByteOrder must not be null");
}
byte[] bytes = unsignedShortToBytes(value);
if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
// 交换高低位
byte tmp = bytes[0];
bytes[0] = bytes[1];
bytes[1] = tmp;
}
return bytes;
}
/**
* 将无符号 short 值(short 类型)转换为指定字节序的字节数组(2字节)。
*
* @param value short 类型,按无符号处理
* @param byteOrder 字节序
* @return 长度为 2 的字节数组
*/
public static byte[] unsignedShortToBytes(short value, ByteOrder byteOrder) {
return unsignedShortToBytes(value & 0xFFFF, byteOrder);
}
// ==================== 字节数组转无符号 short ====================
/**
* 从字节数组的起始位置读取 2 字节,按大端序转换为无符号 short 值(返回 int 类型)。
*
* @param bytes 字节数组
* @param offset 起始偏移量
* @return 无符号 short 值(0 ~ 65535)
* @throws IllegalArgumentException 如果 bytes 为 null 或长度不足
*/
public static int bytesToUnsignedShort(byte[] bytes, int offset) {
if (bytes == null || offset + 2 > bytes.length) {
throw new IllegalArgumentException("Invalid byte array or offset");
}
return ((bytes[offset] & 0xFF) << 8) | (bytes[offset + 1] & 0xFF);
}
/**
* 从字节数组的起始位置读取 2 字节,按指定字节序转换为无符号 short 值。
*
* @param bytes 字节数组
* @param offset 起始偏移量
* @param byteOrder 字节序
* @return 无符号 short 值
*/
public static int bytesToUnsignedShort(byte[] bytes, int offset, ByteOrder byteOrder) {
if (byteOrder == ByteOrder.LITTLE_ENDIAN) {
return ((bytes[offset + 1] & 0xFF) << 8) | (bytes[offset] & 0xFF);
} else {
return bytesToUnsignedShort(bytes, offset);
}
}
// ==================== 其他常见转换(扩展) ====================
/**
* 将 int 值转换为大端序的 4 字节数组。
*/
public static byte[] intToBytes(int value) {
return new byte[]{
(byte) ((value >> 24) & 0xFF),
(byte) ((value >> 16) & 0xFF),
(byte) ((value >> 8) & 0xFF),
(byte) (value & 0xFF)
};
}
/**
* 将大端序的 4 字节数组转换为 int 值。
*/
public static int bytesToInt(byte[] bytes, int offset) {
if (bytes == null || offset + 4 > bytes.length) {
throw new IllegalArgumentException("Invalid byte array or offset");
}
return ((bytes[offset] & 0xFF) << 24)
| ((bytes[offset + 1] & 0xFF) << 16)
| ((bytes[offset + 2] & 0xFF) << 8)
| (bytes[offset + 3] & 0xFF);
}
/**
* 将 long 值转换为大端序的 8 字节数组。
*/
public static byte[] longToBytes(long value) {
return new byte[]{
(byte) ((value >> 56) & 0xFF),
(byte) ((value >> 48) & 0xFF),
(byte) ((value >> 40) & 0xFF),
(byte) ((value >> 32) & 0xFF),
(byte) ((value >> 24) & 0xFF),
(byte) ((value >> 16) & 0xFF),
(byte) ((value >> 8) & 0xFF),
(byte) (value & 0xFF)
};
}
/**
* 将大端序的 8 字节数组转换为 long 值。
*/
public static long bytesToLong(byte[] bytes, int offset) {
if (bytes == null || offset + 8 > bytes.length) {
throw new IllegalArgumentException("Invalid byte array or offset");
}
return ((long) (bytes[offset] & 0xFF) << 56)
| ((long) (bytes[offset + 1] & 0xFF) << 48)
| ((long) (bytes[offset + 2] & 0xFF) << 40)
| ((long) (bytes[offset + 3] & 0xFF) << 32)
| ((long) (bytes[offset + 4] & 0xFF) << 24)
| ((long) (bytes[offset + 5] & 0xFF) << 16)
| ((long) (bytes[offset + 6] & 0xFF) << 8)
| ((long) (bytes[offset + 7] & 0xFF));
}
}
@@ -0,0 +1,170 @@
package com.sunyard.util;
import cn.hutool.core.codec.Base64;
import com.sunyard.RetWrap;
import com.sunyard.SydApiException;
import com.sunyard.constant.CertUsage;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Encoder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Set;
public class CertUtil {
public static String encodeBase64(byte[] data) {
return new BASE64Encoder().encode(data);
}
static {
Security.addProvider(new BouncyCastleProvider());
}
public static X509Certificate convertToX509Cert(String certificateString) throws CertificateException, NoSuchProviderException {
// X509Certificate certificate = null;
// CertificateFactory cf = null;
// try {
// if (certificateString != null && !certificateString.trim().isEmpty()) {
// certificateString = certificateString.replace("-----BEGIN CERTIFICATE-----\n", "")
// .replace("-----END CERTIFICATE-----", ""); // NEED FOR PEM FORMAT CERT STRING
// byte[] certificateData = Base64.decode(certificateString);
// cf = CertificateFactory.getInstance("X509");
// certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certificateData));
// }
// } catch (CertificateException e) {
// throw new CertificateException(e);
// }
// return certificate;
CertificateFactory CF = CertificateFactory.getInstance("X.509", "BC"); // 从证书工厂中获取X.509的单例类
return (X509Certificate) CF.generateCertificate(new ByteArrayInputStream(certificateString.getBytes())); // 将文件流的证书转化为证书类
}
public static String convertToPem(String cert) throws CertificateEncodingException {
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
String end_cert = "\n-----END CERTIFICATE-----";
// byte[] derCert = cert.getEncoded();
byte[] derCert = cert.getBytes();
String pemCertPre = new String(Base64.encode(derCert, true));
String pemCert = cert_begin + pemCertPre + end_cert;
return pemCert;
// StringWriter sw = new StringWriter();
// PemWriter pw = new PemWriter(sw);
// try {
// pw.writeObject(new JcaMiscPEMGenerator(cert));
// }catch ( Exception e ) {
// e.printStackTrace();
// }finally {
// if (null == pw) {
// try {
// pw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
// return sw.toString();
}
/**
* 判断正式是否是国密证书
*
* @param cert 证书 base64 字符
* @return true 国密, false 非国密
*/
public static boolean isSM2Cert(String cert) {
String pemCert;
if(cert.contains("-----BEGIN CERTIFICATE-----")){
pemCert =cert;
}else {
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
String end_cert = "\n-----END CERTIFICATE-----";
pemCert = cert_begin + cert + end_cert;
}
X509Certificate certificate = null;
try {
certificate = convertToX509Cert(pemCert);
} catch (Exception e) {
throw new SydApiException( 0xC101, e );
}
String signAlg = certificate.getSigAlgName();
return signAlg.toUpperCase().indexOf("SM2") >= 0;
}
public static String getDN(String cert) {
String pemCert;
if(cert.contains("-----BEGIN CERTIFICATE-----")){
pemCert =cert;
}else {
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
String end_cert = "\n-----END CERTIFICATE-----";
pemCert = cert_begin + cert + end_cert;
}
X509Certificate certificate = null;
try {
certificate = convertToX509Cert(pemCert);
} catch (Exception e) {
throw new SydApiException( 0xC101, e );
}
return certificate.getSubjectDN().toString();
}
/**
* 判断 p7 是否是国密证书签的
*
* @param pkcs7 pkcs7
* @return true 国密, false 非国密
*/
public static boolean isSignedBySM2Cert(String pkcs7) throws IOException, CertificateException, NoSuchProviderException {
RetWrap ret = ASN1Util.takeOutOriginDataFromPKCS7Sign(pkcs7);
//return isSM2Cert((String) ret.get("cert"));
String cert =(String) ret.get("cert");
if(cert.contains("-----BEGIN CERTIFICATE-----")){
return isSM2Cert(cert);
}else{
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
String end_cert = "\n-----END CERTIFICATE-----";
String pemCert = cert_begin + cert + end_cert;
return isSM2Cert(pemCert);
}
}
public static boolean certUsageCheck(String cert , CertUsage... us ) throws CertificateException, NoSuchProviderException {
if ( null == us || us.length == 0) {
return true;
}
X509Certificate certificate = convertToX509Cert(cert);
boolean[] usage = certificate.getKeyUsage();
if ( null == usage ) {
return false;
}
boolean checkRet = true;
Set<Integer> uset = new HashSet<Integer>();
for ( CertUsage u : us ) {
uset.add( u.ordinal() );
}
for ( int i = 0; i < usage.length; i++ ) {
if ( usage[ i ] ) {
checkRet &= uset.contains( i );
}
}
return checkRet;
}
}
@@ -0,0 +1,18 @@
package com.sunyard.util;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
public class Configure {
public static String getKey(String key) throws IOException {
Properties p = new Properties();
InputStream in = new FileInputStream("./sunyard.properties");
InputStreamReader sr = new InputStreamReader(in, "UTF-8");
p.load(sr);
String value = p.getProperty(key).trim();
return value;
}
}
@@ -0,0 +1,46 @@
package com.sunyard.util;
import java.util.LinkedHashMap;
import java.util.List;
public class DnUtil {
public static LinkedHashMap<String, String> dnToMap(String dn) {
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
String[] kvs = dn.split(",");
for (String kv : kvs) {
String[] ps = kv.split("=");
map.put(ps[0].trim(), ps[1].trim());
}
return map;
}
public static String verifyDn(String dn) {
if ( "true".equals(System.getProperty("com.sunyard.dnsort", "true"))) {
if (dn.startsWith("C=") || dn.startsWith("c=")) {
return dn;
}
// 反转顺序
String[] kvs = dn.split(",");
StringBuilder sb = new StringBuilder();
for (String kv : kvs) {
if (sb.length() > 0) {
sb.insert(0, ",");
}
sb.insert(0, kv);
// if ( sb.length() > 0 ) {
// sb.append(",");
// }
// sb.append( key + "=" + map.get( key ) );
}
return sb.toString();
}
else return dn;
}
}
@@ -0,0 +1,107 @@
package com.sunyard.util;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* IP锁工具类 - 高并发安全实现
*
* 为每个IP地址提供唯一的可重入锁,确保同一IP的操作顺序执行
*/
public class IpLockUtils {
private static final ConcurrentMap<String, ReentrantLock> LOCK_MAP = new ConcurrentHashMap<>();
private static final Object CREATION_LOCK = new Object();
/**
* 获取IP对应的锁(保证唯一性)
* @param ip IP地址
* @return 可重入锁实例
*/
public static ReentrantLock getLockForIp(String ip) {
ReentrantLock lock = LOCK_MAP.get(ip);
if (lock != null) {
return lock;
}
synchronized (CREATION_LOCK) {
// 双重检查
lock = LOCK_MAP.get(ip);
if (lock == null) {
lock = new ReentrantLock(true); // 公平锁
LOCK_MAP.put(ip, lock);
}
return lock;
}
}
/**
* 安全加锁(带超时机制)
* @param ip IP地址
* @param timeout 超时时间
* @param unit 时间单位
* @return 是否成功获取锁
* @throws InterruptedException
*/
public static boolean lockWithTimeout(String ip, long timeout, TimeUnit unit)
throws InterruptedException {
ReentrantLock lock = getLockForIp(ip);
return lock.tryLock(timeout, unit);
}
/**
* 解锁指定IP的锁
* @param ip IP地址
*/
public static void unlockForIp(String ip) {
ReentrantLock lock = LOCK_MAP.get(ip);
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
/**
* 清理未使用的锁(可选)
*/
public static void cleanupUnusedLocks() {
LOCK_MAP.entrySet().removeIf(entry ->
!entry.getValue().isLocked() &&
entry.getValue().getQueueLength() == 0
);
}
/**
* 获取当前锁数量
*/
public static int getLockCount() {
return LOCK_MAP.size();
}
/**
* 获取IP锁状态
* @param ip IP地址
* @return 锁状态字符串
*/
public static String getLockStatus(String ip) {
ReentrantLock lock = LOCK_MAP.get(ip);
if (lock == null) {
return "No lock exists";
}
return String.format("Locked: %s, Queue: %d, HoldCount: %d",
lock.isLocked(), lock.getQueueLength(), lock.getHoldCount());
}
/**
* 重置所有锁
*/
public static void reset() {
synchronized (CREATION_LOCK) {
LOCK_MAP.clear();
}
}
}
@@ -0,0 +1,367 @@
package com.sunyard.util;
import java.util.Collection;
import java.util.Map;
/**
* 参数检查工具类,提供常见的参数校验方法。
* <p>
* 所有方法在校验失败时均抛出 {@link IllegalArgumentException} 异常,
* 并附带包含参数名的明确错误信息。成功时返回被校验的值,便于链式调用。
* </p>
*
* <p>使用示例:
* <pre>{@code
* public void setAge(int age) {
* ParamChecker.checkInRange(age, "age", 0, 150);
* }
*
* public void setName(String name) {
* ParamChecker.checkNotBlank(name, "name");
* }
*
* public void setStatus(int status) {
* ParamChecker.checkInValues(status, "status", 1, 2, 3);
* }
* }</pre>
* </p>
*
* @author Cheney
*/
public final class ParamChecker {
private ParamChecker() {
// 私有构造器,防止实例化
}
/**
* 检查表达式是否为真,若为假则抛出异常。
*
* @param expression 待检查的布尔表达式
* @param message 异常信息
* @throws IllegalArgumentException 如果 expression 为 false
*/
public static void checkArgument(boolean expression, String message) {
if (!expression) {
throw new IllegalArgumentException(message);
}
}
// ==================== 对象非空检查 ====================
/**
* 检查对象不为 null。
*
* @param obj 待检查的对象
* @param paramName 参数名称(用于异常信息)
* @param <T> 对象类型
* @return 传入的对象(便于链式调用)
* @throws IllegalArgumentException 如果 obj 为 null
*/
public static <T> T checkNotNull(T obj, String paramName) {
if (obj == null) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null");
}
return obj;
}
// ==================== 字符串检查 ====================
/**
* 检查字符串不为 null 且长度大于 0(不忽略空白字符)。
*
* @param str 待检查的字符串
* @param paramName 参数名称
* @return 传入的字符串
* @throws IllegalArgumentException 如果 str 为 null 或空字符串
*/
public static String checkNotEmpty(String str, String paramName) {
if (str == null || str.isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空字符串");
}
return str;
}
/**
* 检查字符串不为 null 且去除首尾空白后长度大于 0。
*
* @param str 待检查的字符串
* @param paramName 参数名称
* @return 传入的字符串(原值,非 trim 后结果)
* @throws IllegalArgumentException 如果 str 为 null 或仅包含空白字符
*/
public static String checkNotBlank(String str, String paramName) {
if (str == null || !str.trim().isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null、空字符串或仅包含空白字符");
}
return str;
}
/**
* 检查字符串长度在指定范围内(包含边界)。
*
* @param str 待检查的字符串
* @param paramName 参数名称
* @param min 最小长度(包含)
* @param max 最大长度(包含)
* @return 传入的字符串
* @throws IllegalArgumentException 如果 str 为 null,或长度不在 [min, max] 范围内
*/
public static String checkLengthBetween(String str, String paramName, int min, int max) {
checkNotNull(str, paramName);
if (min > max) {
throw new IllegalArgumentException("内部错误:长度检查的最小值 " + min + " 不能大于最大值 " + max);
}
int len = str.length();
if (len < min || len > max) {
throw new IllegalArgumentException(
String.format("参数 '%s' 的长度 %d 不在允许范围 [%d, %d] 内", paramName, len, min, max));
}
return str;
}
// ==================== 整数(int)检查 ====================
/**
* 检查 int 值大于 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value <= 0
*/
public static int checkPositive(int value, String paramName) {
if (value <= 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 必须为正数,当前值: " + value);
}
return value;
}
/**
* 检查 int 值 >= 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value < 0
*/
public static int checkNonNegative(int value, String paramName) {
if (value < 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为负数,当前值: " + value);
}
return value;
}
/**
* 检查 int 值在指定范围内(包含边界)。
*
* @param value 待检查的值
* @param paramName 参数名称
* @param min 最小值(包含)
* @param max 最大值(包含)
* @return 传入的值
* @throws IllegalArgumentException 如果 value 不在 [min, max] 范围内,或 min > max
*/
public static int checkInRange(int value, String paramName, int min, int max) {
if (min > max) {
throw new IllegalArgumentException("内部错误:范围检查的最小值 " + min + " 不能大于最大值 " + max);
}
if (value < min || value > max) {
throw new IllegalArgumentException(
String.format("参数 '%s' 的值 %d 不在允许范围 [%d, %d] 内", paramName, value, min, max));
}
return value;
}
/**
* 检查 int 值是否等于给定集合中的任意一个值。
*
* @param value 待检查的值
* @param paramName 参数名称
* @param validValues 允许的值列表
* @return 传入的值
* @throws IllegalArgumentException 如果 value 不在 validValues 中,或 validValues 为空
*/
public static int checkInValues(int value, String paramName, int... validValues) {
if (validValues == null || validValues.length == 0) {
throw new IllegalArgumentException("内部错误:允许的值集合不能为空");
}
for (int v : validValues) {
if (value == v) {
return value;
}
}
// 构建允许值字符串用于提示
StringBuilder allowed = new StringBuilder();
for (int i = 0; i < validValues.length; i++) {
if (i > 0) allowed.append(", ");
allowed.append(validValues[i]);
}
throw new IllegalArgumentException(
String.format("参数 '%s' 的值 %d 不在允许值集合 [%s] 中", paramName, value, allowed));
}
// ==================== 长整型(long)检查 ====================
/**
* 检查 long 值大于 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value <= 0
*/
public static long checkPositive(long value, String paramName) {
if (value <= 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 必须为正数,当前值: " + value);
}
return value;
}
/**
* 检查 long 值 >= 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value < 0
*/
public static long checkNonNegative(long value, String paramName) {
if (value < 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为负数,当前值: " + value);
}
return value;
}
/**
* 检查 long 值在指定范围内(包含边界)。
*
* @param value 待检查的值
* @param paramName 参数名称
* @param min 最小值(包含)
* @param max 最大值(包含)
* @return 传入的值
* @throws IllegalArgumentException 如果 value 不在 [min, max] 范围内,或 min > max
*/
public static long checkInRange(long value, String paramName, long min, long max) {
if (min > max) {
throw new IllegalArgumentException("内部错误:范围检查的最小值 " + min + " 不能大于最大值 " + max);
}
if (value < min || value > max) {
throw new IllegalArgumentException(
String.format("参数 '%s' 的值 %d 不在允许范围 [%d, %d] 内", paramName, value, min, max));
}
return value;
}
// ==================== 浮点数(double)简单检查 ====================
/**
* 检查 double 值大于 0(考虑极小正数,不做精度处理)。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value <= 0 或为 NaN
*/
public static double checkPositive(double value, String paramName) {
if (value <= 0 || Double.isNaN(value)) {
throw new IllegalArgumentException("参数 '" + paramName + "' 必须为正数,当前值: " + value);
}
return value;
}
/**
* 检查 double 值 >= 0。
*
* @param value 待检查的值
* @param paramName 参数名称
* @return 传入的值
* @throws IllegalArgumentException 如果 value < 0 或为 NaN
*/
public static double checkNonNegative(double value, String paramName) {
if (value < 0 || Double.isNaN(value)) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为负数或 NaN,当前值: " + value);
}
return value;
}
// ==================== 集合与数组非空检查 ====================
/**
* 检查集合不为 null 且非空。
*
* @param coll 待检查的集合
* @param paramName 参数名称
* @param <T> 集合元素类型
* @return 传入的集合
* @throws IllegalArgumentException 如果 coll 为 null 或空集合
*/
public static <T> Collection<T> checkNotEmpty(Collection<T> coll, String paramName) {
if (coll == null || coll.isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空集合");
}
return coll;
}
/**
* 检查 Map 不为 null 且非空。
*
* @param map 待检查的 Map
* @param paramName 参数名称
* @param <K> 键类型
* @param <V> 值类型
* @return 传入的 Map
* @throws IllegalArgumentException 如果 map 为 null 或空 Map
*/
public static <K, V> Map<K, V> checkNotEmpty(Map<K, V> map, String paramName) {
if (map == null || map.isEmpty()) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空 Map");
}
return map;
}
/**
* 检查数组不为 null 且长度大于 0。
*
* @param array 待检查的数组
* @param paramName 参数名称
* @param <T> 数组元素类型
* @return 传入的数组
* @throws IllegalArgumentException 如果 array 为 null 或长度为 0
*/
public static <T> T[] checkNotEmpty(T[] array, String paramName) {
if (array == null || array.length == 0) {
throw new IllegalArgumentException("参数 '" + paramName + "' 不能为 null 或空数组");
}
return array;
}
// ==================== 布尔条件检查 ====================
/**
* 检查布尔条件为 true。
*
* @param condition 待检查的条件
* @param paramName 参数名称(描述条件含义)
* @throws IllegalArgumentException 如果 condition 为 false
*/
public static void checkTrue(boolean condition, String paramName) {
if (!condition) {
throw new IllegalArgumentException("参数条件 '" + paramName + "' 必须为 true");
}
}
/**
* 检查布尔条件为 false。
*
* @param condition 待检查的条件
* @param paramName 参数名称(描述条件含义)
* @throws IllegalArgumentException 如果 condition 为 true
*/
public static void checkFalse(boolean condition, String paramName) {
if (condition) {
throw new IllegalArgumentException("参数条件 '" + paramName + "' 必须为 false");
}
}
}
@@ -0,0 +1,140 @@
package com.sunyard.util;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.sunyard.SydApiException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
public class QRCodeUtil {
public static void genQRCode(String data,String filepath){
// 图片的尺寸(宽度和高度)
int width = 300;
int height = 300;
// 设置二维码的相关参数
Hashtable<EncodeHintType, Object> hintMap = new Hashtable<>();
hintMap.put(EncodeHintType.MARGIN, 1); // 设置二维码的空白边距
try {
// 创建二维码矩阵
BitMatrix bitMatrix = new MultiFormatWriter().encode(
data,
BarcodeFormat.QR_CODE,
width,
height,
hintMap
);
// 将二维码矩阵转换为图片,并保存
File outputFile = new File(filepath);
MatrixToImageWriter.writeToFile(bitMatrix, "PNG", outputFile);
} catch (Exception e) {
System.err.println("Error occurred while generating QR code: " + e.getMessage());
throw new SydApiException(1001,e);
}
}
public static void genBarCode(String data,String filepath){
// 图片的尺寸(宽度和高度)
int width = 300;
int height = 300;
// 设置二维码的相关参数
Hashtable<EncodeHintType, Object> hintMap = new Hashtable<>();
hintMap.put(EncodeHintType.MARGIN, 1); // 设置二维码的空白边距
try {
// 生成 Code 128 条形码
BitMatrix bitMatrix= new MultiFormatWriter().encode(
data,
BarcodeFormat.PDF_417,
width,
height,
hintMap
);
// 将二维码矩阵转换为图片,并保存
File outputFile = new File(filepath);
MatrixToImageWriter.writeToFile(bitMatrix, "PNG", outputFile);
} catch (Exception e) {
System.err.println("Error occurred while generating QR code: " + e.getMessage());
throw new SydApiException(1001,e);
}
}
public static String readQRCode(String filepath){
// 加载二维码图像
File qrCodeImage = new File(filepath);
// 读取二维码图像
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(qrCodeImage);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 使用 ZXing 的 QRCodeReader 进行解码
QRCodeReader reader = new QRCodeReader();
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
// 解码二维码
Result result = reader.decode(bitmap);
// 提取二维码中的数据
return result.getText();
} catch (NotFoundException e) {
throw new SydApiException(1003,e);
} catch (ChecksumException e) {
throw new SydApiException(1004,e);
} catch (FormatException e) {
throw new SydApiException(1005,e);
}
}
public static String readBarCode(String filepath){
// 加载二维码图像
File BarCodeImage = new File(filepath);
try {
// 读取条形码图像
BufferedImage bufferedImage = ImageIO.read(BarCodeImage);
// 使用 ZXing 的 MultiFormatReader 进行解码
MultiFormatReader reader = new MultiFormatReader();
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// 解码条形码
Result result = reader.decode(bitmap);
// 提取条形码中的数据
return result.getText();
} catch (NotFoundException e) {
throw new SydApiException(1006,e);
} catch (IOException e) {
throw new SydApiException(1007,e);
}
}
}
@@ -0,0 +1,139 @@
package org.bouncycastle.cms;
import com.sunyard.SydApiException;
import org.bouncycastle.asn1.*;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.EncryptedContentInfo;
import org.bouncycastle.asn1.cms.OriginatorInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class SydCmsUtil {
public static Object readContentInfo(
byte[] input) {
ASN1InputStream is = new ASN1InputStream(input);
Object v = null;
try {
v = is.readObject();
} catch (IOException e) {
e.printStackTrace();
}
return v;
}
public static Map<String, Object> getEncryptedContentInfo(ASN1Encodable obj){
Map<String, Object>map = new HashMap<String, Object>();
ASN1Sequence seq = ASN1Sequence.getInstance(obj );
if (seq.size() < 2)
{
throw new IllegalArgumentException("Truncated Sequence Found");
}
ASN1ObjectIdentifier contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0);
map.put( "contentType", contentType );
AlgorithmIdentifier contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance(
seq.getObjectAt(1));
map.put( "contentEncryptionAlgorithm", contentEncryptionAlgorithm );
if (seq.size() > 2)
{
ASN1OctetString encryptedContent = ASN1OctetString.getInstance(
(ASN1TaggedObject)seq.getObjectAt(2), false);
map.put( "encryptedContent", encryptedContent );
}
return map;
}
public static Map<String, Object> getOriginatorInfo(ASN1TaggedObject obj,
boolean explicit){
Map<String, Object>map = new HashMap<String, Object>();
ASN1Sequence seq = ASN1Sequence.getInstance(obj, explicit);
switch (seq.size())
{
case 0: // empty
break;
case 1:
ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0);
switch (o.getTagNo())
{
case 0 :
ASN1Set certs = ASN1Set.getInstance(o, false);
map.put("certs", certs);
break;
case 1 :
ASN1Set crls = ASN1Set.getInstance(o, false);
map.put("crls", crls);
break;
default:
throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo());
}
break;
case 2:
ASN1Set certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false);
map.put("certs", certs);
ASN1Set crls = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false);
map.put("crls", crls);
break;
default:
throw new IllegalArgumentException("OriginatorInfo too big");
}
return map;
}
public static ContentInfo getContentInfo( byte[] input ) {
Object content = readContentInfo( input );
ASN1Sequence seq = ASN1Sequence.getInstance( content );
return new ContentInfo(seq);
}
public static Map<String, Object> readCmsInfo( byte[] input ) throws CMSException {
Map<String, Object>map = new HashMap<String, Object>();
Object content = readContentInfo( input );
ASN1Sequence seq = ASN1Sequence.getInstance( content );
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) seq.getObjectAt(0);
map.put("oid", oid);
seq = ASN1Sequence.getInstance((ASN1TaggedObject) seq.getObjectAt(1), true);
int index = 0;
ASN1Integer version = (ASN1Integer)seq.getObjectAt(index++);
map.put( "version", version );
Object tmp = seq.getObjectAt(index++);
if (tmp instanceof ASN1TaggedObject)
{
OriginatorInfo originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false);
// Map<String, Object>originatorInfo = getOriginatorInfo((ASN1TaggedObject)tmp, false);
map.put( "originatorInfo", originatorInfo );
tmp = seq.getObjectAt(index++);
}
ASN1Set recipientInfos = ASN1Set.getInstance(tmp);
map.put( "recipientInfos", recipientInfos );
EncryptedContentInfo encryptedContentInfo = EncryptedContentInfo.getInstance( seq.getObjectAt(index++) );
// Map<String, Object> encryptedContentInfo = getEncryptedContentInfo(seq.getObjectAt(index++));
map.put( "encryptedContentInfo", encryptedContentInfo );
if(seq.size() > index)
{
ASN1Set unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false);
map.put( "unprotectedAttrs", unprotectedAttrs );
}
return map;
}
}
@@ -0,0 +1,45 @@
package racal.sunyard.main;
import java.util.ArrayList;
import java.util.List;
public class BytesList {
private List<byte[]> bytes = new ArrayList<byte[]>();
public BytesList(){
}
public BytesList(byte[] b){
this.append( b );
}
public void append( byte[] b ) {
bytes.add( b );
}
public byte[] toBytes(){
int len = 0;
if(1== bytes.size()){
return bytes.get(0);
}
for ( byte[] b : bytes ) {
len += b.length;
}
if ( 0 == len ) {
return new byte[0];
}
byte[] buff = new byte[ len ];
int idx = 0;
for ( byte[] b : bytes ) {
System.arraycopy( b, 0, buff, idx, b.length );
idx += b.length;
}
return buff;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,42 @@
package racal.sunyard.main;
import com.sunyard.SydApi;
import com.sunyard.SydApiException;
import com.sunyard.proxy.ProxyInvocationHandler;
public class SydApiClusterBuilder {
public static SydApi SYD_Short_Connect_Ex(String[] pcIpList, int[] iPortList, int iConnectTimeOut, int allDealTimeOut) {
if (pcIpList.length != iPortList.length) {
throw new IllegalArgumentException("ip与端口数量不一致");
}
SydApi4j[] apis = new SydApi4j[pcIpList.length];
int iDealTimeOut = allDealTimeOut / pcIpList.length;
boolean connected = false;
SydApi4j sydApi4j = new SydApi4j();
for (int i = 0; i < pcIpList.length; i++) {
try {
apis[i] = (SydApi4j) sydApi4j.connect(pcIpList[i], iPortList[i], null, iConnectTimeOut, iDealTimeOut);
connected = true;
} catch (Exception e) {
// 忽略错误
// log.error("网络连接错误 {} {} - 忽略", pcIpList[i], iPortList[i]);
}
}
if (!connected) {
// TODO
throw new SydApiException("连接错误", -1);
}
// hsms = apis;
// isShortLinkMode = true;
ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(apis);
return proxyInvocationHandler.getProxy();
}
}
@@ -0,0 +1,4 @@
package racal.sunyard.main;
public class SydApiMuti extends SydApi4j {
}
@@ -0,0 +1,43 @@
package racal.sunyard.main;
import com.sunyard.SydApi;
import com.sunyard.pool.HsmLinkInfo;
import com.sunyard.pool.SydApiPool;
public class SydApiPoolBuilder {
private SydApiPool pool;
public SydApiPoolBuilder(String[] pcIpList, int[] iPortList, int iConnectTimeOut, int iDealTimeOut){
this(pcIpList, iPortList, iConnectTimeOut, iDealTimeOut, true);
}
public SydApiPoolBuilder(String[] pcIpList, int[] iPortList, int iConnectTimeOut, int iDealTimeOut, boolean warmup) {
HsmLinkInfo[] linkInfo = HsmLinkInfo.mutiHsmLinkInfo(pcIpList, iPortList, iConnectTimeOut, iDealTimeOut);
this.pool = new SydApiPool(linkInfo);
if ( warmup ) {
this.warmUp(pcIpList, iPortList, iConnectTimeOut, iDealTimeOut);
}
}
public SydApi build() {
return (SydApi)this.pool.get();
}
public SydApiPool getPool() {
return pool;
}
private void warmUp(String[] pcIpList, int[] iPortList, int iConnectTimeOut, int iDealTimeOut) {
// SydApi4j api = null;
SydApi api = null;
try {
// api = new SydApi4j();
api = SydApiClusterBuilder.SYD_Short_Connect_Ex(pcIpList, iPortList, iConnectTimeOut, iDealTimeOut);
} catch (Exception e) {
} finally {
if (null != api) {
api.disconnect();
}
}
}
}
@@ -0,0 +1,69 @@
package racal.sunyard.main;
public interface SydHashApiTest {
/**
* 计算SM3散列值
* @param sn 证书序号
* @param userId 用户ID
* @param msg 原始数据,二进制的消息块
* @return
*/
byte[] SM3HashSNaId(String sn, String userId, byte[] msg);
/**
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
* @param publicKey 公钥的 DER 编码(可以为空)
* @param msg 原始数据,二进制的消息块
* @param block 消息块标志
* @param mac 上一轮 mac 值,当 mac 不是 null,长度不为 0,则直接从第二包开始。
* @return HASH 值,32 个 Bytes.
*/
byte[] SM3Hash(String publicKey, byte[] msg, int block, byte[] mac);
/**
* 计算SM3散列值
* @param publicKey 公钥的 DER 编码 (03420004 开头)
* @param userId 用户ID
* @param msg 原始数据,二进制的消息块
* @return
*/
byte[] SM3Hash(String publicKey, String userId, byte[] msg);
/**
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
*
* @param publicKey 公钥(可以为空)
* @param msg 原始数据
* @return HASH 值,32 个 Bytes.
*/
byte[] SM3Hash(String publicKey, byte[] msg);
/**
* 输入对指定的原始数据 (无公钥),通过 SM3 算法计算数据的散列值。
*
* @param msg 原始数据
* @return HASH 值,32 个 Bytes.
*/
byte[] SM3Hash(byte[] msg);
public byte[] MACCalc(int alg, int keyType, int fullmode, int maclen, String key, byte[] infoData);
/**
* mac 计算
* @param alg 0=DES 1=3DES 2=SM4 3=AES 4=IDEA 5=SM1 6=3DES-X9.19
* @param keyType 0-TAK 1-ZAK
* @param fullMode 0-弱填充 1 强填充
* @param AK 密钥
* @param infoData <=1024
* @param macLen 1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效)
* @return mac 值 hex 格式
*/
public String MACCalc(int alg, int keyType, String AK, int fullMode, byte[] infoData, int macLen);
public void MACCheck(int alg, int keyType, String AK, int fullMode, byte[] infoData, String mac);
public String calcPBOCMAC(int mode, int keyType, String key, byte[] data, int block, byte[] iv);
}
+116
View File
@@ -0,0 +1,116 @@
import com.sunyard.snmp.SnmpTrapSender;
import com.sunyard.task.AsyncTaskExecutor;
import com.sunyard.task.TaskContext;
import com.sunyard.task.TaskOutcome;
import java.io.File;
import java.io.IOException;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.stream.Collectors;
public class SimpleTest {
public static void main(String[] args) throws Exception {
// testt();
testSnmp();
}
public static void testt() {
AsyncTaskExecutor executor = new AsyncTaskExecutor();
// 使用示例
List<TaskContext<String>> tasks = Arrays.asList(
createTaskContext("1", 1000, "cert"),
createTaskContext("2", 1000, "cert"),
createTaskContext("3", 1000, "cert"),
createTaskContext("4", 1000, "cert")
);
List<TaskOutcome<String>> outcomes = executor.execBatchTasks(tasks);
executor.shutdown();
// 分离成功失败
List<String> successes = outcomes.stream()
.filter(TaskOutcome::isSuccess)
.map(TaskOutcome::getResult)
.collect(Collectors.toList());
List<TaskOutcome<String>> failures = outcomes.stream()
.filter(out -> !out.isSuccess())
.collect(Collectors.toList());
String result = "[" + failures.stream()
.map(p -> p.getContext().getAddress())
.collect(Collectors.joining(",")) + "]";
String message = "信雅达签名服务器:" + result + ",证书: " + "cert" + ",导入失败";
System.out.println(message);
System.out.println("成功节点: " + successes);
System.out.println("失败详情: ");
failures.forEach(f ->
System.out.println(f.getContext().getAddress() + ": " + f.getError().getMessage())
);
}
private static TaskContext<String> createTaskContext(String address, int timeout, String cert) {
Supplier<String> task = () -> importS(address);
return new TaskContext<>(task, 2, Duration.ofSeconds(1), address);
}
public static void test() throws InterruptedException {
List<String> addressList = new ArrayList<>();
addressList.add("1");
addressList.add("2");
addressList.add("3");
addressList.add("4");
addressList.add("6");
CompletableFuture<String>[] futures = new CompletableFuture[addressList.size()];
for(int i = 0; i < addressList.size(); i++){
int finalI = i;
futures[i] = CompletableFuture.supplyAsync(() -> {
return importS(addressList.get(finalI));
});
}
// Thread.sleep(2000);
//汇总失败的任务
List<String> failedTasks = new ArrayList<>();
for(int i = 0; i < futures.length; i++){
if(futures[i].isCompletedExceptionally()){
failedTasks.add(addressList.get(i));
}
}
for (String s : failedTasks) {
System.out.println(s);
try {
String path = "/Users/waner/Work" + "/" + s + ".txt";
File file = new File(path);
file.createNewFile();
} catch (Exception e) {
}
}
}
public static String importS(String s){
// System.out.println("handle:" + s);
if (Integer.parseInt(s) % 2 == 0) {
System.out.println("handle1:" + s);
throw new RuntimeException();
}
return s;
}
public static void testSnmp() throws IOException {
Map<String, String> map = new HashMap<>();
map.put("snmp.target.ip", "172.16.18.113");
map.put("snmp.target.port", "162");
map.put("enterprise.oid", "11");
map.put("snmp.community", "public");
map.put("snmp.version", "1");
// SnmpTrapSender.getInstance().loadConfig(map);
// SnmpTrapSender.getInstance().sendTrap("serve ip[127.0.0.1], import cert failed", 1);
}
}
+54
View File
@@ -0,0 +1,54 @@
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
public class SnmpTrapSenderV2c {
public static void main(String[] args) {
try {
// 1. 创建SNMP对象并监听
TransportMapping<?> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
transport.listen();
// 2. 创建目标地址
Address targetAddress = new UdpAddress("172.16.18.50/162"); // 接收方的IP和端口
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString("public")); // 社区字符串
target.setAddress(targetAddress);
target.setVersion(SnmpConstants.version2c);
target.setTimeout(3000);
target.setRetries(1);
// 3. 创建PDU(协议数据单元)
PDU pdu = new PDU();
// 必须的系统信息
pdu.add(new VariableBinding(SnmpConstants.sysUpTime, new OctetString("12345")));
pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID("1.3.6.1.6.3.1.1.5.3")));
// 添加自定义变量绑定(可选)
pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.1.0"), new OctetString("My Device")));
pdu.add(new VariableBinding(new OID("1.3.6.1.2.1.1.5.0"), new OctetString("Critical Error")));
pdu.setType(PDU.TRAP);
// 4. 发送Trap
snmp.send(pdu, target);
System.out.println("SNMPv2c Trap 发送成功");
snmp.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
+155
View File
@@ -0,0 +1,155 @@
package cmbpoc;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.proto.PacketSection;
import com.sunyard.proto.Util;
import org.junit.*;
import racal.sunyard.main.SydApi4j;
public class FunctionTest {
private SydApi4j api;
private String keypairIndex4Sign = "0000000000000sge00000000001";
private String keypairIndex4Ende = "0000000000000sge00100000001";
private byte[] privateKey4Sign;
private byte[] publicKey4Sign;
private byte[] privateKey4Ende;
private byte[] publicKey4Ende;
private byte[] orgData = new byte[1024];
private byte[] orgData2K = new byte[ 2 * 1024 ];
private byte[] orgData2M = new byte[ 2 * 1024 * 1024 ];
private byte[] orgData10M = new byte[ 10 * 1024 * 1024 ];
private String sign;
@Before
public void start(){
// 调试模式
System.setProperty("com.sunyard.sydapi4j.debug", "true");
// 建立链接(单台)
this.api = (SydApi4j) new SydApi4j().connect("192.168.100.145", 8889, null, 30000);
// RetWrap keypair = this.getPrivateKeyAndPublickKey(keypairIndex4Sign);
// this.publicKey4Sign = Util.hexString2Bytes( keypair.get("pk").toString() );
// this.privateKey4Sign = Util.hexString2Bytes( keypair.get("sk").toString() );
//
// RetWrap keypair4Ende = this.getPrivateKeyAndPublickKey(keypairIndex4Sign);
// this.publicKey4Ende = Util.hexString2Bytes( keypair4Ende.get("pk").toString() );
// this.privateKey4Ende = Util.hexString2Bytes( keypair4Ende.get("sk").toString() );
// 使用预置密钥对
this.publicKey4Sign = Util.hexString2Bytes( "034200046508BC4FE965BEB1D57715C180135FC861FDC6527E82E7FD7A6CA25E7CE9CE75101181D7E2CDD16C1974652B38A045465C7FFBAC700E49F949AE5F4C57AEBEAA" );
this.privateKey4Sign = Util.hexString2Bytes( "00010000CF945DAFF49B9F3AB67A23E1E1BA700FF1F78F5DFFCBB518FD1303A51DABA6FC0000000000000000000000000000000000000000000000000000000000000000" );
this.publicKey4Ende = Util.hexString2Bytes("03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7");
this.privateKey4Ende = Util.hexString2Bytes("00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000");
}
@After
public void stop(){
if ( null != api ) {
this.api.disconnect();
this.api = null;
}
}
@Ignore
@Test
public void genKeyPair(){
// RetWrap r = this.api.SYD_SM2GenKeyPair();
// String pk = r.get("publicKey").toString();
// String sk = r.get("privateKey").toString();
//
// System.out.println("pk=" + pk);
// System.out.println("sk=" + sk);
//
// this.privateKey4Sign = Util.hexString2Bytes(sk);
// this.publicKey4Sign = Util.hexString2Bytes(pk);
RetWrap rw = this.api.SM2GenKeyPair();
byte[] pk = (byte[]) rw.get(SydApi.RET_PUBLIC_KEY);
byte[] sk = (byte[]) rw.get(SydApi.RET_PRIVATE_KEY);
System.out.println("pk=" + Util.bytes2HexString(pk));
System.out.println("sk=" + Util.bytes2HexString(sk));
}
public RetWrap getPrivateKeyAndPublickKey(String keypairIndex){
String pk = this.api.SM2GetPublicKeyC(keypairIndex);
String sk = this.api.SM2GetPrivateKeyC(keypairIndex);
System.out.println("pk=" + pk);
System.out.println("sk=" + sk);
RetWrap retWrap = new RetWrap();
retWrap.put("pk", pk);
retWrap.put("sk", sk);
return retWrap;
}
@Test
public void SYD_SM2_Sign(){
String sign = this.api.SYD_SM2_Sign_HA( SydApi.DATA_HASH, privateKey4Sign, publicKey4Sign, orgData);
this.api.SYD_SM2_Verify_HA(SydApi.DATA_HASH, publicKey4Sign, orgData, sign);
}
@Test
public void SYD_SM2_Sign_2M(){
String sign = this.api.SYD_SM2_Sign_HA( SydApi.DATA_HASH, privateKey4Sign, publicKey4Sign, orgData2M);
this.api.SYD_SM2_Verify_HA(SydApi.DATA_HASH, publicKey4Sign, orgData2M, sign);
}
@Test
public void SYD_SM2_Sign_10M(){
String sign = this.api.SYD_SM2_Sign_HA( SydApi.DATA_HASH, privateKey4Sign, publicKey4Sign, orgData10M);
this.api.SYD_SM2_Verify_HA(SydApi.DATA_HASH, publicKey4Sign, orgData10M, sign);
}
@Test
public void SYD_SM2_Encrypt(){
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData);
System.out.println("密文=" + Util.bytes2HexString(enData));
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
Assert.assertArrayEquals(orgData, deData);
}
@Test
public void SYD_SM2_Encrypt_2K(){
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2K);
System.out.println("密文=" + Util.bytes2HexString(enData));
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
Assert.assertArrayEquals(orgData2K, deData);
}
@Test
public void SYD_SM2_Encrypt_2M(){
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2M);
System.out.println("密文长度=" + enData.length);
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
Assert.assertArrayEquals(orgData2M, deData);
}
@Test
public void SYD_SM2_Encrypt_10M(){
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData10M);
System.out.println("密文=" + Util.bytes2HexString(enData));
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
Assert.assertArrayEquals(orgData10M, deData);
}
}
+156
View File
@@ -0,0 +1,156 @@
package cmbpoc;
import com.sunyard.SydApi;
import com.sunyard.proto.Util;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import racal.sunyard.main.SydApi4j;
import java.util.Random;
public class JmeterTest extends AbstractJavaSamplerClient {
private byte[] publicKey;
private byte[] plainData;
private byte[] encryptedData;
private String sign;
private int sleep = 1;
private byte[] privateKey4Sign;
private byte[] publicKey4Sign;
private byte[] privateKey4Ende;
private byte[] publicKey4Ende;
private String ip ;
private int port;
private int timeout;
private String ip2 ;
private ThreadLocal<SydApi4j> api;
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("function", "sleep");
params.addArgument("sleep", "1");
params.addArgument("plainDataLen", "1024");
params.addArgument("publicKey4Ende", "", "加密用的公钥");
params.addArgument("privateKey4Ende", "", "解密用的公钥");
params.addArgument("publicKey4Sign", "", "验签用的公钥");
params.addArgument("privateKey4Sign", "", "签名用的公钥");
params.addArgument("ip", "192.168.100.145");
params.addArgument("ip2", "172.1.41.96");
params.addArgument("port", "8889");
params.addArgument("timeout", "3000");
return params;
}
@Override
public void setupTest(JavaSamplerContext context) {
// 签名密钥对
String publicKey4Sign = context.getParameter("publicKey4Sign");
if ( null != publicKey4Sign && !publicKey4Sign.isEmpty()) {
this.publicKey4Sign = Util.hexString2Bytes(publicKey4Sign);
}
String privateKey4Sign = context.getParameter("privateKey4Sign");
if ( null != privateKey4Sign && !privateKey4Sign.isEmpty()) {
this.privateKey4Sign = Util.hexString2Bytes(privateKey4Sign);
}
// 加密密钥对
String publicKey4Ende = context.getParameter("publicKey4Ende");
if ( null != publicKey4Ende && !publicKey4Ende.isEmpty()) {
this.publicKey4Ende = Util.hexString2Bytes(publicKey4Ende);
}
String privateKey4Ende = context.getParameter("privateKey4Ende");
if ( null != privateKey4Ende && !privateKey4Ende.isEmpty()) {
this.privateKey4Ende = Util.hexString2Bytes(privateKey4Ende);
}
// 原始数据
int plainDataLen = context.getIntParameter("plainDataLen");
plainData = new byte[plainDataLen];
new Random().nextBytes(plainData);
System.out.println("原始数据长度:" + plainDataLen);
// 校准测试
sleep = context.getIntParameter("sleep", 1);
// api
ip = context.getParameter("ip");
ip2 = context.getParameter("ip2");
port = context.getIntParameter("port");
timeout = context.getIntParameter("timeout");
api = new ThreadLocal<SydApi4j>() {
@Override
public SydApi4j initialValue() {
return (SydApi4j) new SydApi4j().connect(ip, port, null, timeout);
}
};
// 线程开始时准备解密、验签数据
String function = context.getParameter("function");
switch (function) {
case "SYD_SM2_Decrypt":
this.encryptedData = this.api.get().SYD_SM2Encrypt(this.publicKey4Ende, this.plainData);
break;
case "SYD_SM2_Verify":
this.sign = this.api.get().SYD_SM2_Sign_HA(SydApi.DATA_HASH, this.privateKey4Sign, this.publicKey4Sign, this.plainData);
break;
default:
break;
}
}
@Override
public SampleResult runTest(JavaSamplerContext context) {
SampleResult result = new SampleResult();
// 调用待测函数
String function = context.getParameter("function");
result.sampleStart(); // 开始计时
try {
switch (function) {
case "SYD_SM2_Encrypt":
this.api.get().SYD_SM2Encrypt(publicKey4Ende, this.plainData);
break;
case "SYD_SM2_Decrypt":
this.api.get().SYD_SM2Decrypt(privateKey4Ende, this.encryptedData);
break;
case "SYD_SM2_Sign":
this.api.get().SYD_SM2_Sign_HA(SydApi.DATA_HASH, privateKey4Sign, publicKey4Sign, this.plainData);
break;
case "SYD_SM2_Verify":
this.api.get().SYD_SM2_Verify_HA(SydApi.DATA_HASH, publicKey4Sign, this.plainData, this.sign);
break;
case "sleep":
Thread.sleep( this.sleep );
break;
default:
break;
}
// result.setResponseData(encrypted); // 可选
result.setSuccessful(true);
result.setResponseCodeOK();
result.setResponseMessage( function + "执行成功" );
} catch (Exception e) {
result.setSuccessful(false);
result.setResponseCode("500");
result.setResponseMessage( function + "执行失败。" + e.getMessage());
} finally {
result.sampleEnd(); // 结束计时
}
return result;
}
@Override
public void teardownTest(JavaSamplerContext context) {
// 释放资源(如有)
}
}
+51
View File
@@ -0,0 +1,51 @@
package cmbpoc;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
public class JmeterTestTest {
public static void main(String[] args) {
// 1. 创建 JMeter 参数集,并填入您提供的所有参数
Arguments jmeterArgs = new Arguments();
jmeterArgs.addArgument("function", "SYD_SM2_Encrypt");
jmeterArgs.addArgument("sleep", "1");
jmeterArgs.addArgument("plainDataLen", "2048");
jmeterArgs.addArgument("publicKey4Ende", "03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7");
jmeterArgs.addArgument("privateKey4Ende", "00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000");
jmeterArgs.addArgument("ip", "192.168.100.145");
jmeterArgs.addArgument("ip2", "172.1.41.96");
jmeterArgs.addArgument("port", "8889");
jmeterArgs.addArgument("timeout", "3000");
// 2. 基于参数集创建 JMeter 上下文对象
JavaSamplerContext context = new JavaSamplerContext(jmeterArgs);
// 3. 创建您的测试类实例
JmeterTest jmeterTest = new JmeterTest();
try {
// 4. 模拟 JMeter 执行周期:setup -> run -> teardown
jmeterTest.setupTest(context);
SampleResult result = jmeterTest.runTest(context);
if (result != null) {
System.out.println("SampleResult 状态: " + result.getResponseCode());
System.out.println("响应数据: " + result.getResponseDataAsString());
System.out.println("是否成功: " + result.isSuccessful());
} else {
System.out.println("runTest 返回 null,请检查实现逻辑");
}
jmeterTest.teardownTest(context);
} catch (Exception e) {
System.err.println("执行测试时发生异常:");
e.printStackTrace();
}
}
}
+186
View File
@@ -0,0 +1,186 @@
package cmbpoc;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.entity.TimeStats;
import com.sunyard.proto.Util;
import org.junit.*;
import racal.sunyard.main.SydApi4j;
public class PerformanceTest {
private SydApi4j api;
private byte[] privateKey4Ende;
private byte[] publicKey4Ende;
private byte[] orgData2K = new byte[2 * 1024];
private byte[] orgData2M = new byte[2 * 1024 * 1024];
private byte[] orgData10M = new byte[10 * 1024 * 1024];
private static final int TEST_ROUNDS = 10;
@Before
public void start() {
System.setProperty("com.sunyard.sydapi4j.debug", "false");
String ip = System.getProperty("ip", "192.168.100.145");
System.out.println("ip=" + ip);
this.api = (SydApi4j) new SydApi4j().connect(ip, 8889, null, 30000);
this.publicKey4Ende = Util.hexString2Bytes("03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7");
this.privateKey4Ende = Util.hexString2Bytes("00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000");
}
@After
public void stop() {
if (null != api) {
this.api.disconnect();
this.api = null;
}
}
@Test
public void SYD_SM2_Encrypt_Performance_2K() {
System.out.println("=== SYD_SM2_Encrypt Performance Test - 2K Data ===");
long totalEncryptTime = 0;
long totalDecryptTime = 0;
for (int i = 0; i < TEST_ROUNDS; i++) {
long encryptStart = System.currentTimeMillis();
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2K);
long encryptEnd = System.currentTimeMillis();
long decryptStart = System.currentTimeMillis();
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
long decryptEnd = System.currentTimeMillis();
totalEncryptTime += (encryptEnd - encryptStart);
totalDecryptTime += (decryptEnd - decryptStart);
Assert.assertArrayEquals(orgData2K, deData);
}
double avgEncryptTime = (double) totalEncryptTime / TEST_ROUNDS;
double avgDecryptTime = (double) totalDecryptTime / TEST_ROUNDS;
double encryptThroughput = (2.0 / avgEncryptTime) * 1000;
double decryptThroughput = (2.0 / avgDecryptTime) * 1000;
System.out.println("Test Rounds: " + TEST_ROUNDS);
System.out.println("Data Size: 2KB");
System.out.printf("Average Encrypt Time: %.2f ms%n", avgEncryptTime);
System.out.printf("Average Decrypt Time: %.2f ms%n", avgDecryptTime);
System.out.printf("Encrypt Throughput: %.2f KB/s%n", encryptThroughput);
System.out.printf("Decrypt Throughput: %.2f KB/s%n", decryptThroughput);
System.out.println();
}
@Test
public void SYD_SM2_Encrypt_Performance_2M() {
System.out.println("=== SYD_SM2_Encrypt Performance Test - 2M Data ===");
long totalEncryptTime = 0;
long totalDecryptTime = 0;
for (int i = 0; i < TEST_ROUNDS; i++) {
long encryptStart = System.currentTimeMillis();
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2M);
long encryptEnd = System.currentTimeMillis();
long decryptStart = System.currentTimeMillis();
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
long decryptEnd = System.currentTimeMillis();
totalEncryptTime += (encryptEnd - encryptStart);
totalDecryptTime += (decryptEnd - decryptStart);
Assert.assertArrayEquals(orgData2M, deData);
}
double avgEncryptTime = (double) totalEncryptTime / TEST_ROUNDS;
double avgDecryptTime = (double) totalDecryptTime / TEST_ROUNDS;
double encryptThroughput = (2048.0 / avgEncryptTime) * 1000;
double decryptThroughput = (2048.0 / avgDecryptTime) * 1000;
System.out.println("Test Rounds: " + TEST_ROUNDS);
System.out.println("Data Size: 2MB");
System.out.printf("Average Encrypt Time: %.2f ms%n", avgEncryptTime);
System.out.printf("Average Decrypt Time: %.2f ms%n", avgDecryptTime);
System.out.printf("Encrypt Throughput: %.2f KB/s%n", encryptThroughput);
System.out.printf("Decrypt Throughput: %.2f KB/s%n", decryptThroughput);
System.out.println();
}
@Test
public void SYD_SM2_Encrypt_Performance_10M() {
System.out.println("=== SYD_SM2_Encrypt Performance Test - 10M Data ===");
long totalEncryptTime = 0;
long totalDecryptTime = 0;
for (int i = 0; i < TEST_ROUNDS; i++) {
long encryptStart = System.currentTimeMillis();
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData10M);
long encryptEnd = System.currentTimeMillis();
long decryptStart = System.currentTimeMillis();
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
long decryptEnd = System.currentTimeMillis();
totalEncryptTime += (encryptEnd - encryptStart);
totalDecryptTime += (decryptEnd - decryptStart);
Assert.assertArrayEquals(orgData10M, deData);
}
double avgEncryptTime = (double) totalEncryptTime / TEST_ROUNDS;
double avgDecryptTime = (double) totalDecryptTime / TEST_ROUNDS;
double encryptThroughput = (10240.0 / avgEncryptTime) * 1000;
double decryptThroughput = (10240.0 / avgDecryptTime) * 1000;
System.out.println("Test Rounds: " + TEST_ROUNDS);
System.out.println("Data Size: 10MB");
System.out.printf("Average Encrypt Time: %.2f ms%n", avgEncryptTime);
System.out.printf("Average Decrypt Time: %.2f ms%n", avgDecryptTime);
System.out.printf("Encrypt Throughput: %.2f KB/s%n", encryptThroughput);
System.out.printf("Decrypt Throughput: %.2f KB/s%n", decryptThroughput);
System.out.println();
}
@Test
public void SYD_SM2_Encrypt_TimeStats_2M() {
System.out.println("=== SYD_SM2_Encrypt Time Statistics Test - 2M Data ===");
// 预热
for (int i = 0; i < 2; i++) {
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2M);
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData);
}
// 正式测试
TimeStats encryptStats = new TimeStats();
TimeStats decryptStats = new TimeStats();
byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2M, encryptStats);
byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData, decryptStats);
Assert.assertArrayEquals(orgData2M, deData);
System.out.println("\n--- 加密阶段时间统计 ---");
System.out.printf("发送阶段: %d ms (%.1f%%), 发送次数: %d%n",
encryptStats.getSendTime(), encryptStats.getSendPercentage(), encryptStats.getSendCount());
System.out.printf("计算阶段: %d ms (%.1f%%)%n",
encryptStats.getComputeTime(), encryptStats.getComputePercentage());
System.out.printf("接收阶段: %d ms (%.1f%%), 接收次数: %d%n",
encryptStats.getReceiveTime(), encryptStats.getReceivePercentage(), encryptStats.getReceiveCount());
System.out.printf("加密总耗时: %d ms%n", encryptStats.getTotalTime());
System.out.println("\n--- 解密阶段时间统计 ---");
System.out.printf("发送阶段: %d ms (%.1f%%), 发送次数: %d%n",
decryptStats.getSendTime(), decryptStats.getSendPercentage(), decryptStats.getSendCount());
System.out.printf("计算阶段: %d ms (%.1f%%)%n",
decryptStats.getComputeTime(), decryptStats.getComputePercentage());
System.out.printf("接收阶段: %d ms (%.1f%%), 接收次数: %d%n",
decryptStats.getReceiveTime(), decryptStats.getReceivePercentage(), decryptStats.getReceiveCount());
System.out.printf("解密总耗时: %d ms%n", decryptStats.getTotalTime());
System.out.println("\n--- 汇总 ---");
long totalTime = encryptStats.getTotalTime() + decryptStats.getTotalTime();
System.out.printf("加密解密总耗时: %d ms%n", totalTime);
System.out.printf("加密吞吐量: %.2f KB/s%n", (2048.0 / encryptStats.getTotalTime()) * 1000);
System.out.printf("解密吞吐量: %.2f KB/s%n", (2048.0 / decryptStats.getTotalTime()) * 1000);
}
}
@@ -0,0 +1,84 @@
package cmbpoc;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.proto.Util;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
public class SignatureVerifyTest {
private SydApi4j api;
private byte[] orgData;
private String SM2dn;
@Before
public void setUp() {
System.setProperty("com.sunyard.sydapi4j.debug", "true");
this.api = (SydApi4j) new SydApi4j().connect("172.1.41.139", 8889, null, 3000);
this.orgData = "Hello, World! 测试数据".getBytes();
this.SM2dn = "C=cn,O=CFCA OCA1 SM2,OU=Local RA OCA1,OU=Units,CN=041@N91330108762038374D@sunyard@00000064";
}
@After
public void tearDown() {
if (api != null) {
this.api.disconnect();
this.api = null;
}
}
@Test
public void testP1SignAndVerify() {
byte[] sign = this.api.SYD_NakedSign(orgData, SM2dn);
Assert.assertNotNull("P1签名结果不应为空", sign);
System.out.println("P1签名结果: " + Util.bytes2HexString(sign));
boolean verifyResult = this.api.SYD_NakedVerify(orgData, sign, SM2dn);
Assert.assertTrue("P1验签应通过", verifyResult);
System.out.println("P1验签结果: " + verifyResult);
}
@Test
public void testP7DetachSignAndVerify() {
String sign = this.api.detachedSign(1, orgData, SM2dn);
Assert.assertNotNull("P7 Detach签名结果不应为空", sign);
System.out.println("P7 Detach签名结果: " + sign);
boolean verifyResult = this.api.detachedVerify(1, orgData, sign);
Assert.assertTrue("P7 Detach验签应通过", verifyResult);
System.out.println("P7 Detach验签结果: " + verifyResult);
}
@Test
public void testP7AttachSignAndVerify() throws Exception {
String sign = this.api.attachedSign(orgData, SM2dn);
Assert.assertNotNull("P7 Attach签名结果不应为空", sign);
System.out.println("P7 Attach签名结果: " + sign);
boolean verifyResult = this.api.attachedVerify(sign);
Assert.assertTrue("P7 Attach验签应通过", verifyResult);
System.out.println("P7 Attach验签结果: " + verifyResult);
}
@Test
public void testDigitalEnvelopeEncryptAndDecrypt() {
RetWrap genResult = this.api.generateDEByDn(SM2dn, orgData);
Assert.assertNotNull("数字信封生成结果不应为空", genResult);
byte[] cipherKey = (byte[]) genResult.get(SydApi.RET_CIPHER_KEY);
Assert.assertNotNull("数字信封密文密钥不应为空", cipherKey);
System.out.println("数字信封密文: " + new String(cipherKey));
RetWrap decryptResult = this.api.decryptDEByDN(SM2dn, cipherKey);
Assert.assertNotNull("数字信封解密结果不应为空", decryptResult);
byte[] decryptedData = (byte[]) decryptResult.get("oData");
Assert.assertNotNull("解密数据不应为空", decryptedData);
Assert.assertArrayEquals("解密数据应与原始数据一致", orgData, decryptedData);
System.out.println("数字信封解密结果: " + new String(decryptedData));
}
}
@@ -0,0 +1,45 @@
package com.sunyard.sydapi;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
/**
* 传化签名验签demo
* */
public class ChuanhuaDemo1 {
public static void main(String[] args) {
// 调试模式
System.setProperty("com.sunyard.sydapi4j.debug", "true");
// 建立链接(单台)
SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.0.100", 8889, null, 1000);
try {
final String testSN1 = "1004282451";
final String testSN2 = "1004282452";
byte[] testData = "1234567812345678信达雅SUNYARDsunyard".getBytes("UTF-8");
System.out.println("\n\n----- 用指定的证书私钥对指定的数据进行数字签名。 -----");
String signPri = api.netSign(testSN1, testData);
System.out.print("sign : ");
System.out.println(signPri);
// 验签传原始数据
System.out.println("\n\n----- 用指定的证书私钥对指定的数据进行数字验证。 -----");
if (api.netVerify(testSN1, testData, signPri)) {
System.out.println("验证通过");
} else {
System.out.println("验证失败");
}
}catch (Exception e){
e.printStackTrace();
}finally {
api.disconnect();
}
}
}
@@ -0,0 +1,65 @@
package com.sunyard.sydapi;
import com.sunyard.proto.Util;
import org.junit.Assert;
import racal.sunyard.main.SydApi4j;
/**
* 传化国密加解密demo
* */
public class ChuanhuaDemo2 {
/*public static void write(String file, byte[] content) {
try {
File f = new File(file);
if (!f.exists()) {
f.createNewFile();
}
FileOutputStream fos = new FileOutputStream(f);
fos.write(content);
} catch (Exception e) {
System.out.println("写入文件 " + file + " 异常");
}
}*/
public static void main(String[] args){
// 调试模式
System.setProperty("com.sunyard.sydapi4j.debug", "true");
// 建立链接(单台)
// SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.0.100", 8889, null, 1000);
SydApi4j api = (SydApi4j) new SydApi4j().connect("172.16.18.59", 8889, null, 1000);
try{
// final String testSN1 = "1004282451";//签名
// final String testSN2 = "1004282452";//加密
final String userId = "1747";
byte[] testData = "1234567812345678信达雅SUNYARDsunyard@!#$%^加密s".getBytes("GBK");
String pk = api.SM2GetPublicKeyC(userId, 1);
System.out.println("pk= " + pk);
System.out.println("\n\n----- 用输入的会话密钥,对指定报文数据进行加密处理。 SM2 -----");
String sdata = api.SM2Encrypt(Util.hexString2Bytes(pk), testData);
System.out.println("加密后的数据: " + sdata);
System.out.println("\n\n----- 用输入的会话密钥,对指定报文数据进行解密处理。 SM2 -----");
byte[] data = api.SM2DecryptC(userId, sdata);
Assert.assertArrayEquals(testData, data);
System.out.println("解密后的数据: " + new String(data));
// write("./data.txt",data);
}catch (Exception e){
e.printStackTrace();
}finally {
api.disconnect();
}
}
}
@@ -1,55 +0,0 @@
package com.sunyard.sydapi.loadrunner;
import com.sunyard.sydapi.loadrunner.action1.Actions;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
public class ShangTest {
private static final String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
private static final byte[] testData = new byte[ 4 * 1024 ];
private SydApi4j api = null;
public void init() throws Exception {
if ( null == api ) {
api = (SydApi4j) new SydApiBuilder()
.setIp("172.16.18.59") // 192.168.0.162
.setPort( 8889 )
.useDebugMode()
.build();
}
}
public void action(){
String sign = api.attachedSign(testData, dn);
boolean ret = api.attachedVerify( sign );
assert ret;
sign = api.SYD_DetachedSign(testData, dn);
ret = api.SYD_DetachedVerify( testData, sign );
assert ret;
}
public void end(){
if (null != this.api ) {
this.api.disconnect();
}
}
public static void main(String[] args) throws Throwable {
System.out.println( SydApi4j.getVersion() );
// Actions test = new Actions();
ShangTest test = new ShangTest();
test.init();
test.action();
test.end();
}
}
@@ -1,44 +0,0 @@
package com.sunyard.sydapi.loadrunner.action1;
/*
* LoadRunner Java script. (Build: _build_number_)
*
* Script Description:
*
*/
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
public class Actions
{
private static final byte[] testData = new byte[ 4 * 1024 ];
private SydApi4j api = null;
public int init() throws Throwable {
if ( null == api ) {
api = (SydApi4j) new SydApiBuilder()
.setIp("172.16.18.59")
.setPort( 8889 )
.useDebugMode()
.build();
}
return 0;
}//end of init
public int action() throws Throwable {
api.SM3Hash( testData );
return 0;
}//end of action
public int end() throws Throwable {
if (null != this.api ) {
this.api.disconnect();
}
return 0;
}//end of end
}
@@ -1,203 +0,0 @@
package com.sunyard.sydapi.test;
import com.sunyard.RetWrap;
import com.sunyard.SydApi;
import com.sunyard.proto.Util;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
import java.io.UnsupportedEncodingException;
import static com.sunyard.sydapi.util.PrintUtil.printByteArray;
import static com.sunyard.sydapi.util.PrintUtil.printRetWrap;
/**
* 农行北分海淀支行-军队资金集中收付系统
*/
public class ABCNorthBranch {
SydApi4j api;
// SM2密钥索引
String SM2PrivateKeyTag = "111111111111115100000000001";
// SM2公钥
String SM2PublicKey = null;
// SM2私钥
String SM2PrivateKey = null;
// SM4密钥索引
String SM4PrivateKeyTag = "000000000000000100011111111";
// SM4密钥
String SM4Key = null;
@Before
public void before() {
System.setProperty("com.sunyard.sydapi4j.debug", "true");
api = (SydApi4j) new SydApi4j().connect("61.164.40.82", 8889, null, 5000);
SM2PublicKey = api.SM2GetPublicKeyC(SM2PrivateKeyTag);
SM2PrivateKey = api.SM2GetPrivateKeyC(SM2PrivateKeyTag);
SM4Key = new String((byte[]) api.readKey(SM4PrivateKeyTag).get("key"));
System.out.println("=========================================密钥获取完成=========================================");
}
@After
public void after() {
try {
this.api.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
// A4
@Test
public void testComposeKey() {
String[] strs = {"583034303438393445374238444531323942344646344546393838394535364132", "583934443335443836454631463332313344353543343738323246383744333835"};
RetWrap rw = api.composeKey("000", strs);
printRetWrap(rw);
}
// 测试通过
// 74
@Test
public void testSM2SignC2() {
String thisOrgData = "FFFFFFFFFFFFFFFF";
String s = api.SM2SignC(1, SM2PrivateKeyTag, Util.hexString2Bytes(SM2PublicKey), thisOrgData.getBytes());
System.out.println(s);
}
// 测试通过
// 74
@Test
public void testSM2SignC3() {
String thisOrgData = "FFFFFFFFFFFFFFFF";
String s = api.SM2SignC(0, SM2PrivateKey, Util.hexString2Bytes(SM2PublicKey), thisOrgData.getBytes());
System.out.println(s);
}
// 75
@Test
public void testSM2SignAndVerify() {
String orgData = "11111111111111";
// 这里,不管是签名还是验签,都需要在外部做一次hash。
byte[] hash = api.SM3Hash(SM2PublicKey, orgData.getBytes());
/**
* 用私钥签名(外部私钥)
* @param nOrgDataType 签名数据类型,0 : hash 1 : 原数据
* @param privateKey LMK34-35 下加密的私钥
* @param orgData “签名数据类型”为 0 时:HASH 值。“签名数据类型”为 1 时:要签名的信息
* @return 签名的 base64 编码
*/
String s = api.SM2Sign(SydApi.DATA_HASH, Util.hexString2Bytes(SM2PrivateKey), hash);
// 这里的签名结果已经符合条件了,不需要做转换
System.out.println("签名结果: " + s);
System.out.println("decBase64:" + Util.bytes2HexString(Util.decodeBase64(s)));
/**
* 用指定的公钥对指定的原始数据进行数字签名验证(PKCS#1)
* @param nOrgDataType 签名数据类型,SydApi.DATA_ORIGIN(1) 原始数据 SydApi.DATA_HASH(0) : hash 后的类型
* @param publicKey 公钥串,DER编码,HEX格式
* @param orgData 待签名的原始数据,“签名数据类型”为 0 时:HASH 值。“签名数据类型”为 1 时:要签名的信息
* @param base64Sign 签名数据 (DER 编码 + Base64 编码)
* @return 验签是否通过
*/
boolean b = api.SM2Verify(SydApi.DATA_HASH, Util.hexString2Bytes(SM2PublicKey), hash, s);
System.out.println("验签结果: " + b);
}
// 测试通过
// 75
@Test
public void testSM2Verify3() {
String thisOrgData = "FFFFFFFFFFFFFFFF";
String s = api.SM2SignC(1, SM2PrivateKeyTag, Util.hexString2Bytes(SM2PublicKey), thisOrgData.getBytes());
System.out.println(s);
boolean b = api.SM2Verify(Util.hexString2Bytes(SM2PublicKey), thisOrgData.getBytes(), s);
System.out.println(b);
}
// 测试通过
// E0
@Test
public void testSM4EncryptDataCBC() {
String msg = "1111111111111111111111";
byte[] bytes = api.SM4EncryptDataCBC(0, SM4Key, 0, 0, msg.getBytes());
printByteArray(bytes);
}
// 测试通过
// E0
@Test
public void testSM4DecryptDataCBC() {
String msg = "11111111111";
byte[] bytes = api.SM4EncryptDataCBC(0, SM4Key, 0, 0, msg.getBytes());
byte[] bytes1 = api.SM4DecryptDataCBC(0, SM4Key, 0, 0, bytes);
printByteArray(bytes1, false);
}
// 测试通过
// E0
@Test
public void testSM4EncryptFileDataCBC() {
String inFilePath = "C:\\Users\\edgar\\Desktop\\fsdownload\\test\\in1.txt";
String outFilePath = "C:\\Users\\edgar\\Desktop\\fsdownload\\test\\in2.txt";
boolean b = api.SM4EncryptFileDataCBC(0, SM4Key, 0, 0, inFilePath, outFilePath);
System.out.println(b);
}
// 测试通过
// E0
@Test
public void testSM4DecryptFileDataCBC() throws UnsupportedEncodingException {
String outFilePath = "C:\\Users\\edgar\\Desktop\\fsdownload\\test\\in2.txt";
String outFilePath2 = "C:\\Users\\edgar\\Desktop\\fsdownload\\test\\out1.txt";
boolean b = api.SM4DecryptFileDataCBC(0, SM4Key, 0, 0, outFilePath, outFilePath2);
System.out.println(b);
}
// LF
@Test
public void testReadKey() {
RetWrap retWrap = api.readKey(SM4PrivateKeyTag);
printRetWrap(retWrap);
}
// QQ
@Test
public void testSM2GetPublicKeyC3() {
String s = api.SM2GetPublicKeyC(SM2PrivateKeyTag);
System.out.println(s);
}
// QP
@Test
public void testSM2GetPrivateKeyC() {
String s = api.SM2GetPrivateKeyC(SM2PrivateKeyTag);
System.out.println(s);
}
}
@@ -0,0 +1,90 @@
package com.sunyard.sydapi.test;
import com.github.houbb.junitperf.core.annotation.JunitPerfConfig;
import com.github.houbb.junitperf.core.rule.JunitPerfRule;
import com.sunyard.RetWrap;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.sunyard.sydapi.util.PrintUtil.printRetWrap;
public class CertTest {
public static void main(String[] args) {
//System.setProperty("com.sunyard.sydapi4j.debug", "true");
SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.1.129", 8889, null, 1000);
try{
List<String>dns = api.getAllCert();
System.out.println(Arrays.toString( dns.toArray() ) );
// String sql=" certtype in (0,2) "; //签名解密
// String sql2=" certtype in (1,3) "; //验签加密
//
// ArrayList<String> m_certs =new ArrayList<String>();
// //查出证书总数,一次次的拿出来
// RetWrap allCert = api.getAllCert(0);
// printRetWrap(allCert);
// Integer allnum = (Integer) allCert.get("certAllNum");//总数
// List<String> certs = (List<String>)allCert.get("certDNs");//部分证书列表
// System.out.println(certs.toString());
// m_certs.addAll(certs);
// int loop = allnum%16;//循环次数
// for (int i = 1; i < loop; i++) {
// RetWrap partCert= api.getAllCert(16*i);
// List<String> partcerts = (List<String>)partCert.get("certDNs");
// m_certs.addAll(partcerts);
// }
// System.out.println("证书:"+m_certs);
// System.out.println("aa"+m_certs.get(20));
}catch (Exception e){
e.printStackTrace();
}finally {
api.disconnect();
}
}
// 测试参数
// private static final int threads = 1;
// private static final long duration = 120000;
// private static final long warmUp = 30000;
//
//
// @Rule
// public JunitPerfRule junitPerfRule = new JunitPerfRule();
// SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.1.129",8889,null,3000);
//
//
// @BeforeClass
// public static void init() throws UnsupportedEncodingException {
// System.out.println("begin");
//
// }
//
//
// @AfterClass
// public static void after() {
// System.out.println("all over");
// }
//
// @Test
// @JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
// public void getAllCert(){
// try {
// api.getAllCert(0);
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// }
}
@@ -0,0 +1,114 @@
package com.sunyard.sydapi.test;
import com.sunyard.proto.Util;
import org.junit.runners.MethodSorters;
import racal.sunyard.main.SydApi4j;
import com.github.houbb.junitperf.core.annotation.JunitPerfConfig;
import com.github.houbb.junitperf.core.rule.JunitPerfRule;
import org.junit.*;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class P1P7Test {
// 全局配置
private static final String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
// 测试参数
private static final int threads = 1;
private static final long duration = 120000;
private static final long warmUp = 30000;
// 原始数据
private static final byte[] data1k = new byte[ 1024 * 4];
private static final byte[] data1m = new byte[ 1024 * 1024 ];
// 临时数据
private static String pk = null;
private static String dm_1k;
private static String dm_1m = null;
private static byte[] p1sign_1k;
private static byte[] p1sign_1m = null;
private static String p7dsign_1k;
private static String p7dsign_1m = null;
private static String p7asign_1k;
private static String p7asign_1m = null;
@Rule
public JunitPerfRule junitPerfRule = new JunitPerfRule();
SydApi4j api = (SydApi4j) new SydApi4j().connect("192.168.0.200",8889,null,3000);
@BeforeClass
public static void init() throws UnsupportedEncodingException {
System.out.println("begin");
}
@AfterClass
public static void after() {
System.out.println("all over");
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void p1_sign_1k(){
p1sign_1k= api.SYD_NakedSign(data1k, dn);
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void p1_verify_1k(){
api.SYD_NakedVerify( data1k, p1sign_1k, dn );
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void p7a_sign_1k() throws UnsupportedEncodingException {
p7asign_1k = api.attachedSign(data1k, dn);
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void p7a_verify_1k(){
api.attachedVerifyAndGetAll( p7asign_1k );
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void p7d_sign_1k(){
p7dsign_1k = api.sm3AndDetachedSign(data1k, pk, dn);
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void p7d_verify_1k(){
api.sm3AndDetachedVerify(data1k, pk, p7dsign_1k );
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void dm_aen_1k() {
dm_1k = String.valueOf(api.generateDEByDn(dn, data1k));
}
@Test
@JunitPerfConfig(threads = threads, warmUp = warmUp, duration = duration)
public void dm_de_1k() {
api.decryptDEByDN(dn, Util.hexString2Bytes(dm_1k));
}
}
@@ -0,0 +1,73 @@
package com.sunyard.sydapi.test;
import com.sunyard.RetWrap;
import com.sunyard.proto.Util;
import com.sunyard.util.ASN1Util;
import racal.sunyard.main.SydApi4j;
import racal.sunyard.main.SydApiBuilder;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class RSASignVertify {
private static final String RSADN = "C=cn,O=CFCA TEST CA,OU=CIPSTEST,OU=Units,CN=041@3CIPSCNSHCLR@CN000000129@00000018";
private static final byte[] orgData={1,2,3,4,5,6};
private static final String SM2DN = "C=CN,O=123,OU=23,OU=23,CN=32";
// public p1
// p7attach
// p7detach
public static void main(String[] args) throws IOException {
//System.setProperty("com.sunyard.sydapi4j.debug", "true");
//long startTime = System.currentTimeMillis(); //设置系统时间
SydApiBuilder builder = new SydApiBuilder().setIp("172.16.18.59");
SydApi4j api = (SydApi4j) builder.build();
//
// byte[] nakedSign = api.SYD_NakedSign(1,orgData,RSADN);
// System.out.println("nakedSign"+nakedSign);
// byte[] sm2Sign = api.SYD_NakedSign(orgData,SM2DN);
// System.out.println("sm2Sign:"+sm2Sign);
//
// boolean nakedVerify = api.SYD_NakedVerify(1, orgData, nakedSign, RSADN);
// System.out.println(nakedVerify);
// boolean nakedVerify2 = api.SYD_NakedVerify( orgData, sm2Sign, SM2DN);
// System.out.println(nakedVerify2);
// String attachedSign = api.attachedSign(orgData, SM2DN);
// //System.out.println(attachedSign);
// boolean attachedVerify = api.attachedVerify(attachedSign);
// System.out.println(attachedVerify);
//
// String attachedSign2 = api.attachedSign(1,orgData, RSADN);
// String attachedSign3 = api.attachedSign(2,orgData, RSADN);
// String attachedSign4 = api.attachedSign(3,orgData, RSADN);
// System.out.println("签名1:"+attachedSign2);
// System.out.println("签名2:"+attachedSign3);
// System.out.println("签名3:"+attachedSign4);
// boolean attachedVerify2 = api.attachedVerify(attachedSign2);
// RetWrap retWrap = ASN1Util.takeOutOriginDataFromPKCS7Sign(attachedSign2);
// System.out.println(attachedVerify2);
// byte[] orgData = (byte[]) retWrap.get("orgData");
// String cert = (String) retWrap.get("cert");
// System.out.println(Util.bytes2HexString(orgData));
// System.out.println(Util.bytes2HexString(Util.decodeBase64(cert)));
// System.out.println("证书:"+Util.bytes2HexString(Util.encodeBase64(RSADN.getBytes("GBK")).getBytes("GBK")));
String detachedSign = api.detachedSign(1, orgData, SM2DN);
System.out.println(detachedSign);
String detachedSign2 = api.detachedSign(1,0, orgData, RSADN);
System.out.println(detachedSign2);
boolean detachedVerify = api.detachedVerify(1, orgData, detachedSign);
boolean detachedVerify2 = api.detachedVerify(1,0, orgData, detachedSign2);
System.out.println(detachedVerify);
System.out.println(detachedVerify2);
// String RSAsign = api.attachedSign(1, orgData.getBytes("GBK"), RSADN);
}
}
@@ -0,0 +1,415 @@
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.Assert;
import org.junit.Before;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
import java.io.UnsupportedEncodingException;
/**
* 上清例子
*/
public class Shanqing {
SydApi4j api;
@Before
public void before() {
// 通过设置debug的属性开启debug,如果不设置则默认不打开
System.setProperty("com.sunyard.sydapi4j.debug", "true");
api = (SydApi4j) new SydApi4j().connect("192.168.0.200", 8889, null, 1000);
}
@After
public void after() {
try {
this.api.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 流程演示
*/
@Test
public void testProcess() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = new byte[2 * 1024 * 1024];
// 签名
String sign = api.attachedSign(orgData, dn);
System.out.println("签名结果: " + sign);
// 生成数字信封
RetWrap retWrap = api.generateDEByDn(dn, sign.getBytes());
byte[] cipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
System.out.println("数字信封: " + new String(cipherKey));
// 解密数字信封
RetWrap retWrap1 = api.decryptDEByDN(dn, cipherKey);
byte[] oData = (byte[]) retWrap1.get("oData");
System.out.println("原数据: " + retWrap1.get("oData"));
// 验签
RetWrap verify = api.attachedVerifyAndGetAll(oData);
if (verify != null) {
System.out.println("x509公钥: " + Util.bytes2HexString(((X509) verify.get("x509")).getPubKey()));
System.out.println("签名原数据: " + Util.bytes2HexString((byte[]) (verify.get("oData"))));
}
}
//
// 测试通过
// 73
@Test
public void testSM2ConfirmSessionKeyC() {
String userId = "8012";
byte[] data = "12343242".getBytes();
// 通过用户id获取公钥
String pk = api.SM2GetPublicKeyC(userId, SydApi.FOR_ENCRYPT);
// 生成数字信封
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);
// 使用生成的对称密钥加密数据
byte[] dataEnc = api.SYMEncryptData(SydApi.NALG_SM4, sessionKey, data);
// 解密数字信封
RetWrap retWrap1 = api.SM2ConfirmSessionKeyC(userId, cipherKey);
printRetWrap(retWrap1);
sessionKey = (String) retWrap1.get(SydApi.RET_SESSION_KEY);
kcv = (String) retWrap1.get(SydApi.RET_KCV);
// 使用解密出来的对称密钥解密数据
byte[] bytes1 = api.SYMDecryptData(SydApi.NALG_SM4, sessionKey, dataEnc);
System.out.println("解密后的数据:" + new String(bytes1));
}
@Test
public void testDetachedSignAndVerify1() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
String orgData = "111111213323143243243";
String sign = api.attachedSign(orgData.getBytes(), dn);
System.out.println("签名结果: " + sign);
System.out.println("签名结果 hex : " + Util.bytes2HexString(Util.decodeBase64(sign)));
boolean verify = api.attachedVerify(sign);
System.out.println("验签结果: " + verify);
Assert.assertTrue(verify);
}
@Test
public void testDetachedSignAndVerify2() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
String orgData = "111111213323143243243";
String sign = api.attachedSignSoft(orgData.getBytes(), dn);
System.out.println("签名结果: " + sign);
System.out.println("签名结果 hex: " + Util.bytes2HexString(Util.decodeBase64(sign)));
boolean verify = api.attachedVerify(sign);
System.out.println("验签结果: " + verify);
Assert.assertTrue(verify);
}
@Test
public void testDetachedSignAndVerify3() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = new byte[3 * 1024];
String sign = api.attachedSign(orgData, dn);
System.out.println("签名结果: " + sign);
System.out.println("签名结果 hex: " + Util.bytes2HexString(Util.decodeBase64(sign)));
boolean verify = api.attachedVerify(sign);
System.out.println("验签结果: " + verify);
Assert.assertTrue(verify);
}
@Test
public void testDetachedSignAndVerify8() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = new byte[8 * 1024];
String sign = api.attachedSign(orgData, dn);
System.out.println("签名结果: " + sign);
System.out.println("签名结果 hex: " + Util.bytes2HexString(Util.decodeBase64(sign)));
boolean verify = api.attachedVerify(sign);
System.out.println("验签结果: " + verify);
Assert.assertTrue(verify);
}
// 测试通过
// 8018
@Test
public void testAttachedSignAndVerify() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
String orgData = "111111213323143243243";
String sign = api.attachedSign(orgData.getBytes(), dn);
System.out.println("签名结果: " + sign);
System.out.println("签名结果 hex : " + Util.bytes2HexString(Util.decodeBase64(sign)));
boolean verify = api.attachedVerify(sign);
System.out.println("验签结果: " + verify);
}
@Test
public void testAttachedSignAndVerifyGetX509() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = "111111213323143243243".getBytes();
String sign = api.attachedSign(orgData, dn);
System.out.println("签名结果: " + sign);
X509 verify = api.attachedVerifyAndGetX509(sign);
System.out.println("验签结果: " + Util.bytes2HexString(verify.getPubKey()));
}
@Test
public void testAttachedSignAndVerifyRD() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
String orgData = "111111213323143243243";
String sign = api.attachedSign(orgData.getBytes(), dn);
System.out.println("签名结果: " + sign);
byte[] verify = api.attachedVerifyRD(sign);
System.out.println("验签结果: " + Util.bytes2HexString(verify));
}
@Test
public void testAttachedSignAndVerifyGetAll() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = "111111213323143243243".getBytes();
String sign = api.attachedSign(orgData, dn);
System.out.println("签名结果: " + sign);
RetWrap verify = api.attachedVerifyAndGetAll(sign);
if (verify != null) {
System.out.println("x509公钥: " + Util.bytes2HexString(((X509) verify.get("x509")).getPubKey()));
System.out.println("签名原数据: " + verify.get("oData"));
}
}
@Test
public void testAttachedSignAndVerifyGetAll8k() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = new byte[ 8 * 1024 ];
String sign = api.attachedSign(orgData, dn);
System.out.println("签名结果: " + sign);
RetWrap verify = api.attachedVerifyAndGetAll(sign);
if (verify != null) {
System.out.println("x509公钥: " + Util.bytes2HexString(((X509) verify.get("x509")).getPubKey()));
System.out.println("签名原数据: " + verify.get("oData"));
}
}
@Test
public void testAttachedSignAndVerifyGetX509C() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = "111111213323143243243".getBytes();
byte[] sign = api.attachedSignC(orgData, dn);
System.out.println("签名结果: " + sign);
X509 verify = api.attachedVerifyAndGetX509(sign);
System.out.println("验签结果: " + Util.bytes2HexString(verify.getPubKey()));
}
@Test
public void testAttachedSignAndVerifyRDC() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
String orgData = "111111213323143243243";
byte[] sign = api.attachedSignC(orgData.getBytes(), dn);
System.out.println("签名结果: " + sign);
byte[] verify = api.attachedVerifyRD(sign);
System.out.println("验签结果: " + Util.bytes2HexString(verify));
}
@Test
public void testAttachedSignAndVerifyGetAllC() {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] orgData = "111111213323143243243".getBytes();
byte[] sign = api.attachedSignC(orgData, dn);
System.out.println("签名结果: " + sign);
RetWrap verify = api.attachedVerifyAndGetAll(sign);
if (verify != null) {
System.out.println("x509公钥: " + Util.bytes2HexString(((X509) verify.get("x509")).getPubKey()));
System.out.println("签名原数据: " + verify.get("oData"));
}
}
@Test
public void testDecryptDE54k12() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] oData = new byte[4 * 1024];
RetWrap retWrap = api.generateDEByDnHsm(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDNSoft(dn, new String(CipherKey));
printRetWrap(retWrap1);
byte[] deData = (byte[]) retWrap1.get("oData");
Assert.assertArrayEquals(deData, oData);
}
@Test
public void testDecryptDE54k21() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] oData = new byte[4 * 1024];
RetWrap retWrap = api.generateDEByDnSoft(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDNHsm(dn, new String(CipherKey));
printRetWrap(retWrap1);
byte[] deData = (byte[]) retWrap1.get("oData");
Assert.assertArrayEquals(deData, oData);
}
@Test
public void testDecryptDE54k() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] oData = new byte[4 * 1024];
RetWrap retWrap = api.generateDEByDn(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDN(dn, CipherKey);
printRetWrap(retWrap1);
}
@Test
public void testDecryptDE54kr() throws UnsupportedEncodingException {
String dn = "CN=YCCA@黄金交易所@Zhuangj@1,OU=Individual-2,OU=YCCA,O=CFCA OCA1,C=CN";
byte[] oData = new byte[4 * 1024];
RetWrap retWrap = api.generateDEByDn(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDN(dn, CipherKey);
printRetWrap(retWrap1);
}
@Test
public void testDecryptDE520M() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] oData = new byte[20 * 1024 * 1024];
RetWrap retWrap = api.generateDEByDn(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDN(dn, CipherKey);
printRetWrap(retWrap1);
}
@Test
public void testDecryptDE58k() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] oData = new byte[8 * 1024];
RetWrap retWrap = api.generateDEByDn(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDN(dn, CipherKey);
printRetWrap(retWrap1);
}
@Test
public void testDecryptDE5() throws UnsupportedEncodingException {
String dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1";
byte[] oData = "00001111222233".getBytes();
RetWrap retWrap = api.generateDEByDn(dn, oData);
byte[] CipherKey = (byte[]) retWrap.get(SydApi.RET_CIPHER_KEY);
byte[] sessionKey = (byte[]) retWrap.get(SydApi.RET_SESSION_KEY);
printRetWrap(retWrap);
RetWrap retWrap1 = api.decryptDEByDN(dn, CipherKey);
printRetWrap(retWrap1);
}
// 测试通过
// 76
@Test
public void testSM3Hash() {
String orgData = "FFFFFFFFFFFFFFFF";
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((byte[]) o));
}
} else {
System.out.println(s + ":" + o);
}
}
}
}
@@ -1,14 +1,13 @@
package com.sunyard.sydapi.test;
import com.sunyard.SydApi;
import com.sunyard.cert.X509;
import com.sunyard.proto.Util;
import racal.sunyard.main.SydApi4j;
public class Test74 {
public static void main(String[] args) {
SydApi4j.SYD_Set_Parameter_HA("unkown", "172.16.17.162", 8889, 1000);
SydApi4j.SYD_Set_Parameter_HA("unkown", "172.16.17.161", 8889, 1000);
SydApi4j api = (SydApi4j) new SydApi4j();

Some files were not shown because too many files have changed in this diff Show More