武汉人行指令整合

This commit is contained in:
zhoubin 2021-08-11 13:56:19 +08:00
parent 73ad09279e
commit 45f81f4685
15 changed files with 1479 additions and 259 deletions

97
DProto/90.xml Normal file
View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>90</hex>
</command>
<data extend="data">
<equipType len="16" cn="设备型号">
设备型号
</equipType>
<equipNo len="16" cn="设备序号">
设备型号
</equipNo>
<equipSkLen :value="equipSkLen()" cn="设备密钥私钥长度">
设备密钥私钥长度
</equipSkLen>
<equipSk cn="设备密钥私钥">
设备密钥私钥
</equipSk>
<equipPkLen :value="equipPkLen()" cn="设备密钥公钥长度">
设备密钥公钥长度
</equipPkLen>
<equipPK cn="设备密钥公钥">
设备密钥公钥
</equipPK>
<manuPkLen :value="manuPkLen()" cn="厂商公钥长度">
厂商公钥长度
</manuPkLen>
<manuPk cn=" 厂商公钥">
厂商公钥
</manuPk>
<authSign len="64" cn="授权签名">
授权签名
</authSign>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>91</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
</options>
</error>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function equipSkLen(){
var data = $packet.data;
return data.equipSk.length;
}
function equipPkLen(){
var data = $packet.data;
return data.equipPk.length;
}
function manuPkLen(){
var data = $packet.data;
return data.manuPk.length;
}
</script>
</packet>

77
DProto/91.xml Normal file
View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>91</hex>
</command>
<data extend="data">
<equipSkLen :value="equipSkLen()" cn="设备密钥私钥长度">
设备密钥私钥长度
</equipSkLen>
<equipSk cn="设备密钥私钥">
设备密钥私钥
</equipSk>
<equipPkLen :value="equipPkLen()" cn="设备密钥公钥长度">
设备密钥公钥长度
</equipPkLen>
<equipPK cn="设备密钥公钥">
设备密钥公钥
</equipPK>
<authSign len="64" cn="授权签名">
授权签名
</authSign>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>92</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
</options>
</error>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function equipSkLen(){
var data = $packet.data;
return data.equipSk.length;
}
function equipPkLen(){
var data = $packet.data;
return data.equipPk.length;
}
</script>
</packet>

73
DProto/92.xml Normal file
View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>92</hex>
</command>
<data extend="data">
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>93</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
</options>
</error>
<equipType len="16" cn="设备型号" >
设备型号
</equipType>
<equipNo len="16" cn="设备序号" >
设备序号
</equipNo>
<equipPkLen len="4" cn="设备密钥公钥长度">
设备密钥公钥长度,在下一个域中的字节长度
</equipPkLen>
<equipPk :len="resequipPkLen()" cn="设备密钥公钥" >
设备密钥公钥
</equipPk>
<authSign len="64" cn="授权签名">
授权签名
</authSign>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function resequipPkLen(){
return Util.a2i( $final.getSection('data').getSection('equipPkLen') )
}
</script>
</packet>

64
DProto/97.xml Normal file
View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>97</hex>
</command>
<data extend="data">
<hashData :len="32" cn="哈希数据">
哈希数据
</hashData>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>98</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
</options>
</error>
<signatureLen len="4" cn="签名的字节长度">
签名的字节长度
</signatureLen>
<signature :len="signatureLen()" cn="签名的 DER 编码">
签名的 DER 编码
</signature>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function signatureLen() {
return Util.a2i( $final.getSection('data').getSection('signatureLen') )
}
</script>
</packet>

63
DProto/98.xml Normal file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>98</hex>
</command>
<data extend="data">
<tokenLen len="4" :value="tokenLen()" cn="Token密文长度">
Token密文长度
</tokenLen>
<token cn=" Toke密文">
Toke密文
</token>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>99</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
</options>
</error>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function tokenLen(){
var data = $packet.data;
return data.token.length;
}
</script>
</packet>

81
DProto/99.xml Normal file
View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" ?>
<packet extend="base">
<req>
<command>
<hex>99</hex>
</command>
<data extend="data">
<certiContentLen len="4" :value="certiContentLen()" cn="认证内容长度">
认证内容长度
</certiContentLen>
<certiContent cn="认证内容">
认证内容
</certiContent>
<tailSep len="1" :if=" null != $packet.data.tail " cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为
“X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</req>
<res>
<command>
<hex>9A</hex>
</command>
<data>
<error len="2" cn="错误码" format="X" :catch="catchError('%s')">
<options>
<option cn="无错误">
<hex>00</hex>
</option>
</options>
</error>
<equipType len="16" cn="设备型号" >
设备型号
</equipType>
<equipNo len="16" cn="设备序号" >
设备序号
</equipNo>
<authenCodeLen len="4" cn="认证码长度">
认证码长度
</authenCodeLen>
<authenCode :len="authenCodeLen()" cn="认证码" >
认证码
</authenCode>
<tailSep len="1" required="false" cn="尾分隔">
可选项。如果显示消息尾域,则该域必须显示。值为 “X19”。
<hex>19</hex>
</tailSep>
<tail maxLen="32" required="false" cn="尾部">
可选项。最大长度为 32个字符。
</tail>
</data>
</res>
<script>
function certiContentLen(){
var data = $packet.data;
return data.certiContent.length;
}
function authenCodeLen(){
return Util.a2i( $final.getSection('data').getSection('authenCodeLen') )
}
</script>
</packet>

View File

@ -27,6 +27,7 @@
<zmk cn="ZMK" :if="hasZmk()">
仅当模式为 1 时才显示该 ZMK 域
27位的索引号16位机构号+3位密钥类型+8位密钥索引号
</zmk>
<keySolution len="1" cn="加密输出密钥的密钥方案" :if="1 == $packet.data.mode$option">

View File

@ -5,6 +5,7 @@ import com.sunyard.inf.*;
import com.sunyard.inf.customize.SydHAApi;
import com.sunyard.inf.customize.SydQNUCApi;
import com.sunyard.inf.customize.SydSDNXApi;
import racal.sunyard.main.SydApiBuilder;
import java.io.InputStream;
@ -12,7 +13,7 @@ import java.io.InputStream;
* Created by Cheney on 2017/11/11.
* 程序调用接口
*/
public interface SydApi extends SydRawApi, SydCertApi, SydCryptionApi, SydGenApi, SydSVApi, SydHAApi, SydQNUCApi, SydPledge, SydPINOpt {
public interface SydApi extends SydRawApi, SydCertApi, SydCryptionApi, SydGenApi, SydSVApi, SydHAApi, SydQNUCApi, SydPledge, SydPINOpt, SydManufactureApi {
byte ALG_AES = 0x30;
byte ALG_SM4 = 0x31;
@ -67,7 +68,7 @@ public interface SydApi extends SydRawApi, SydCertApi, SydCryptionApi, SydGenApi
*/
SydApi connect(String ip, int port, String pwd, int connectTimeout, int readTimeout);
void init(SydApiBuilder builder);
/**
* 断开连接

View File

@ -352,5 +352,25 @@ interface SydSYMApi {
*/
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);
//通过索引读取对称秘钥
String readKey(String index);
}

View File

@ -2,6 +2,8 @@ package com.sunyard.inf;
import com.sunyard.RetWrap;
import java.io.UnsupportedEncodingException;
/**
* 密钥生成相关接口
@ -128,6 +130,57 @@ public interface SydGenApi {
*/
RetWrap SM2GenSessionKey(String publicKey);
/**
* 生成数字信封
* @param publicKey 公钥
* @return
* CipherKey: 公钥加密的会话密钥,DER 编码HEX 格式,
* SessionKey: 本地LMK 加密的会话密钥HEX 格式 ,
* KCV: 会话密钥的检验值HEX 格式长度为 16H
*/
RetWrap genDigitalEnvelope(String publicKey);
/**
* 解密数字信封
*
* @param sk 私钥索引
* @param cipherKey 密文
* @return sessionKey LMK加密下的密钥
*/
String deDigitalEnvelope(String sk, String cipherKey);
/**
* @Description: 数字信封加密数据,会员专用
* @Param: [pk, inPutDatamsgId]
* @return: byte[] 格式sessionByPk+\r\n++\r\n+密文
* @Author: wp
* @Date: 2020/11/20
*/
String genDigitalEnvelopeWithDM(String pk, String inPutDataStr,String msgId) throws UnsupportedEncodingException;
/**
* 数字信封加密数据票价所定制格式
* @param pk 公钥值
* @param inPutData 报文明文
* @return 报文密文 格式sessionByPk(base64)+\r\n+密文(base64)
* @throws UnsupportedEncodingException
*/
String genDigitalEnvelopeWithData(String pk,String inPutData) throws UnsupportedEncodingException;
/**
* 解密数字信封解密数据
* @param sk 私钥索引
* @param inPutData 报文密文
* @return 报文明文
* @throws UnsupportedEncodingException
*/
String deDigitalEnvelopeWithData(String sk, String inPutData) throws UnsupportedEncodingException;
/**
* 将秘钥从 PK 加密转为 LMK 加密
* @param skIndex 私钥索引
* @param sessionKey 会话秘钥密文
* @return 会话秘钥密文
*/
String transKeyFromPkToLmk(String skIndex, String sessionKey);
/**
* 此函数用于会话密钥的接收用于接收端
@ -148,6 +201,17 @@ public interface SydGenApi {
*/
RetWrap SM2ConfirmSessionKey(String sk, String cipherKey);
/**
* 产生对称密钥通过公钥加密生成网联格式的数字信封
* @param dn * X509 证书DN
* @param nAlg 算法标识,0:AES1SM4
* @return RetWrap 包含 CipherKey SessionKey KCV
* CipherKey 公钥加密的会话密钥 ,BASE64 编码
* SessionKey 本地LMK 加密的会话密钥HEX 格式, 本地 LMK 加密的会话密钥长度HEX 格式(不包括第 1 个字符)一般为 33 Bytes默认输入值为缓冲区的大小
* KCV 会话密钥的检验值HEX 格式长度为 32H
*/
RetWrap generateDEByDn(byte[] dn, byte nAlg) throws Exception;
/**
* 产生对称密钥通过公钥加密生成网联格式的数字信封

View File

@ -0,0 +1,72 @@
package com.sunyard.inf;
import com.sunyard.RetWrap;
/**
* @program: ssphsm
* @description:
* @author: wp
* @create: 2021-03-09 19:25
**/
public interface SydManufactureApi {
/**
* 设置设备证书信息
* @param equipType 设备型号
* @param equipNo 设备序号
* @param equipSk 设备密钥私钥
* @param equipPk 设备密钥公钥
* @param manuPk 厂商公钥
* @param authSign 授权签名
* @return 是否设置成功
*/
boolean setDevCert(String equipType, String equipNo, byte[] equipSk, byte[] equipPk, byte[] manuPk, byte[] authSign);
/**
* 更换设备证书信息
* @param equipSk 设备密钥私钥
* @param equipPk 设备密钥公钥
* @param authSign 授权签名
* @return 是否设置成功
*/
boolean changeDevCert(byte[] equipSk, byte[] equipPk, byte[] authSign);
/**
* @Description 查询设备证书信息 -> pass
* @Param
* @Return com.sunyard.RetWrap
* @Author wp
* @Date 2020/9/30 16:42
**/
RetWrap getDeviceCertiInfo();
/**
* @Description 加密机版本号 -> pass
* @Param [num]
* @Return com.sunyard.RetWrap
* @Author wp
* @Date 2020/9/30 16:42
**/
RetWrap getVersion(String num);
/**
* 设备签名
* @param orgData 哈希数据
* @return 签名的 DER 编码
*/
String deviceSignC(byte[] orgData);
/**
* TOKEN导入
* @param token 设备公钥加密的 Token 密文
* @return 是否导入成功
*/
boolean setToken(byte[] token);
/**
* 计算设备认证码
* @param certiContent 认证内容
* @return 认证码
*/
byte[] calcAuthHead(byte[] certiContent);
}

View File

@ -2,6 +2,7 @@ package com.sunyard.inf;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
/**
* 签名验签相关接口
@ -274,6 +275,19 @@ interface SydDetachedSVApi {
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=最后块

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,15 @@ public class SydApiBuilder {
private boolean useEBCDMode = false;
private boolean useETEncrypt = false;
private ClassLoader classLoader;
private String encode="UTF-8";
public String getEncode() {
return encode;
}
public void setEncode(String encode) {
this.encode = encode;
}
public SydApi build() throws ClassNotFoundException, IllegalAccessException, InstantiationException {

View File

@ -0,0 +1,54 @@
package com.sunyard.sydapi.test;
import com.sunyard.RetWrap;
import com.sunyard.proto.Util;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import racal.sunyard.main.SydApi4j;
public class TestAllMethods {
SydApi4j api;
@Before
public void before() {
System.setProperty("com.sunyard.sydapi4j.debug", "true");
api = (SydApi4j) new SydApi4j().connect("172.16.17.163", 8889, null, 1000);
}
@After
public void after() {
try {
this.api.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
// 1.1.1 对称密钥产生
@Test
public void testGenSymmetricKey() {
RetWrap retWrap = api.genSymmetricKey("000", 'X');
String lmkKey = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("lmkKey"))));
String keyCheck = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("keyCheck"))));
System.out.println("lmkKey:" + lmkKey);
System.out.println("keyCheck:" + keyCheck);
}
// 1.1.2 对称密钥产生, 对比之前添加了可产生ZMK加密下的密钥
@Test
public void testGenSymKey() {
// RetWrap retWrap = api.genSymKey(0, "000", 'X', null);
// String lmkKey = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("lmkKey"))));
// String keyCheck = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("keyCheck"))));
// System.out.println("lmkKey:" + lmkKey);
// System.out.println("keyCheck:" + keyCheck);
RetWrap retWrap = api.genSymKey(1, "000", 'X', "1");
String lmkKey = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("lmkKey"))));
String keyCheck = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("keyCheck"))));
System.out.println("lmkKey:" + lmkKey);
System.out.println("keyCheck:" + keyCheck);
}
}