From 45f81f468544583e712ed9a6a90e56db8ecb73b5 Mon Sep 17 00:00:00 2001 From: zhoubin <2023106681@qq.com> Date: Wed, 11 Aug 2021 13:56:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A6=E6=B1=89=E4=BA=BA=E8=A1=8C=E6=8C=87?= =?UTF-8?q?=E4=BB=A4=E6=95=B4=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DProto/90.xml | 97 ++ DProto/91.xml | 77 ++ DProto/92.xml | 73 ++ DProto/97.xml | 64 + DProto/98.xml | 63 + DProto/99.xml | 81 ++ DProto/A0.xml | 1 + src/main/java/com/sunyard/SydApi.java | 5 +- .../java/com/sunyard/inf/SydCryptionApi.java | 20 + src/main/java/com/sunyard/inf/SydGenApi.java | 64 + .../com/sunyard/inf/SydManufactureApi.java | 72 ++ src/main/java/com/sunyard/inf/SydSVApi.java | 14 + .../java/racal/sunyard/main/SydApi4j.java | 1044 +++++++++++++---- .../racal/sunyard/main/SydApiBuilder.java | 9 + .../sunyard/sydapi/test/TestAllMethods.java | 54 + 15 files changed, 1479 insertions(+), 259 deletions(-) create mode 100644 DProto/90.xml create mode 100644 DProto/91.xml create mode 100644 DProto/92.xml create mode 100644 DProto/97.xml create mode 100644 DProto/98.xml create mode 100644 DProto/99.xml create mode 100644 src/main/java/com/sunyard/inf/SydManufactureApi.java create mode 100644 src/test/java/com/sunyard/sydapi/test/TestAllMethods.java diff --git a/DProto/90.xml b/DProto/90.xml new file mode 100644 index 0000000..1061fa2 --- /dev/null +++ b/DProto/90.xml @@ -0,0 +1,97 @@ + + + + + + 90 + + + + 设备型号 + + + + 设备型号 + + + + 设备密钥私钥长度 + + + + 设备密钥私钥 + + + + 设备密钥公钥长度 + + + + 设备密钥公钥 + + + + 厂商公钥长度 + + + + 厂商公钥 + + + + 授权签名 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 + “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + 91 + + + + + + + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + \ No newline at end of file diff --git a/DProto/91.xml b/DProto/91.xml new file mode 100644 index 0000000..1e0e491 --- /dev/null +++ b/DProto/91.xml @@ -0,0 +1,77 @@ + + + + + + 91 + + + + 设备密钥私钥长度 + + + + 设备密钥私钥 + + + + 设备密钥公钥长度 + + + + 设备密钥公钥 + + + + 授权签名 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 + “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + 92 + + + + + + + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + \ No newline at end of file diff --git a/DProto/92.xml b/DProto/92.xml new file mode 100644 index 0000000..cb5eb3e --- /dev/null +++ b/DProto/92.xml @@ -0,0 +1,73 @@ + + + + + + 92 + + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 + “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + 93 + + + + + + + + + + 设备型号 + + + + 设备序号 + + + + 设备密钥公钥长度,在下一个域中的字节长度 + + + + 设备密钥公钥 + + + + 授权签名 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + \ No newline at end of file diff --git a/DProto/97.xml b/DProto/97.xml new file mode 100644 index 0000000..c19b616 --- /dev/null +++ b/DProto/97.xml @@ -0,0 +1,64 @@ + + + + + + 97 + + + + 哈希数据 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 + “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + 98 + + + + + + + + + + 签名的字节长度 + + + + 签名的 DER 编码 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + \ No newline at end of file diff --git a/DProto/98.xml b/DProto/98.xml new file mode 100644 index 0000000..05a4205 --- /dev/null +++ b/DProto/98.xml @@ -0,0 +1,63 @@ + + + + + + 98 + + + + + Token密文长度 + + + + Toke密文 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 + “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + 99 + + + + + + + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + \ No newline at end of file diff --git a/DProto/99.xml b/DProto/99.xml new file mode 100644 index 0000000..adb79e3 --- /dev/null +++ b/DProto/99.xml @@ -0,0 +1,81 @@ + + + + + + 99 + + + + + 认证内容长度 + + + + 认证内容 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 + “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + + + 9A + + + + + + + + + + 设备型号 + + + + 设备序号 + + + + 认证码长度 + + + + 认证码 + + + + 可选项。如果显示消息尾域,则该域必须显示。值为 “X’19”。 + 19 + + + + 可选项。最大长度为 32个字符。 + + + + + + \ No newline at end of file diff --git a/DProto/A0.xml b/DProto/A0.xml index b9e2e4d..7586951 100644 --- a/DProto/A0.xml +++ b/DProto/A0.xml @@ -27,6 +27,7 @@ 仅当模式为 1 时才显示该 ZMK 域 + 27位的索引号:16位机构号+3位密钥类型+8位密钥索引号 diff --git a/src/main/java/com/sunyard/SydApi.java b/src/main/java/com/sunyard/SydApi.java index 3db809f..bff4102 100644 --- a/src/main/java/com/sunyard/SydApi.java +++ b/src/main/java/com/sunyard/SydApi.java @@ -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); /** * 断开连接 diff --git a/src/main/java/com/sunyard/inf/SydCryptionApi.java b/src/main/java/com/sunyard/inf/SydCryptionApi.java index ec63a67..47bce83 100644 --- a/src/main/java/com/sunyard/inf/SydCryptionApi.java +++ b/src/main/java/com/sunyard/inf/SydCryptionApi.java @@ -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); } diff --git a/src/main/java/com/sunyard/inf/SydGenApi.java b/src/main/java/com/sunyard/inf/SydGenApi.java index 8aa105f..bc1fe66 100644 --- a/src/main/java/com/sunyard/inf/SydGenApi.java +++ b/src/main/java/com/sunyard/inf/SydGenApi.java @@ -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, inPutData,msgId] + * @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:AES,1:SM4 + * @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; /** * 产生对称密钥,通过公钥加密生成网联格式的数字信封。 diff --git a/src/main/java/com/sunyard/inf/SydManufactureApi.java b/src/main/java/com/sunyard/inf/SydManufactureApi.java new file mode 100644 index 0000000..7e3ef56 --- /dev/null +++ b/src/main/java/com/sunyard/inf/SydManufactureApi.java @@ -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); +} diff --git a/src/main/java/com/sunyard/inf/SydSVApi.java b/src/main/java/com/sunyard/inf/SydSVApi.java index 65bdfaa..78219b7 100644 --- a/src/main/java/com/sunyard/inf/SydSVApi.java +++ b/src/main/java/com/sunyard/inf/SydSVApi.java @@ -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=最后块 diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java index 4b22325..87678ec 100644 --- a/src/main/java/racal/sunyard/main/SydApi4j.java +++ b/src/main/java/racal/sunyard/main/SydApi4j.java @@ -79,6 +79,7 @@ public class SydApi4j implements SydApi { } + @Override public RetWrap SYD_SM2GenKeyPair() { ProtoQN proto = new ProtoQN(); @@ -691,7 +692,60 @@ public class SydApi4j implements SydApi { return true; } + @Override + public X509 detachedVerifyAndGetX509(int dataType, byte[] orgData, String sign) { + Proto8006 proto = new Proto8006(); //pset.getProtocolReqRender("75"); + + // 填充数据 + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + + if (dataType == DATA_HASH) { + data.put("hashFlag", 'P'); + data.put("hash", orgData); + } else { + data.put("originData", orgData); + } + + data.put("signData", sign.getBytes()); + data.put("flag$option", 1); + // 渲染发送 + ByteBuffer bb = proto.rend(packet); + synchronized (this) { + // 响应解析 + bb = syncRead(syncSend(bb)); + } + + Packet p = proto.parse(bb, packet); + Map ret = p.toMap(); + + if ( + !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes()) + ) { + throw new SydApiException("包序号不匹配", -4); + } + ret = (Map) ret.get("data"); + PacketSection error = (PacketSection) ret.get("error"); + byte[] be = error.getBytes(); + if ((0 != (be[0] ^ be[1]))) { + return null; + } + + PacketSection info = (PacketSection) ret.get("info"); + byte[] pCertInfo = info.getBytes(); + + String certInfo = new String(pCertInfo); + int index = certInfo.indexOf("-----BEGIN CERTIFICATE-----"); + certInfo = certInfo.substring(index); + System.out.println(certInfo); + X509 x509 = GetX509CertInfo(certInfo); + x509.setPubKey(certInfo.getBytes()); + return x509; + } @Override public boolean detachedVerify(int dataType, byte[] orgData, byte[] sign) { @@ -863,7 +917,7 @@ public class SydApi4j implements SydApi { ret = (Map) ret.get("data"); PacketSection error = (PacketSection) ret.get("error"); byte[] be = error.getBytes(); - if ( ( 0 != (be[0] ^ be[1]))) { + if ((0 != (be[0] ^ be[1]))) { throw new SydApiException(error.getInfo(), error.autoInt()); } @@ -881,10 +935,10 @@ public class SydApi4j implements SydApi { r.put("certLenMax", Integer.parseInt(Util.bytes2HexString(Util.toArray(bb)).substring(60, 62), 16)); List certs = new ArrayList(); - while( bb.limit() - bb.position() >= 128 ) { - byte[] cert = new byte[ 128 ]; - bb.get( cert ); - certs.add( new String(cert, "GBK") ); + while (bb.limit() - bb.position() >= 128) { + byte[] cert = new byte[128]; + bb.get(cert); + certs.add(new String(cert, "GBK")); } r.put("certDNs", certs.toArray(new String[0])); @@ -905,10 +959,10 @@ public class SydApi4j implements SydApi { PacketSN sn = PacketSN.gen(); packet.put("header", sn.getSn().array()); - data.put("certData", certData ); + data.put("certData", certData); - if(null != organizationId && organizationId.length > 0){ - data.put("organizationId", organizationId ); + if (null != organizationId && organizationId.length > 0) { + data.put("organizationId", organizationId); } // int length = certData.length; @@ -941,7 +995,7 @@ public class SydApi4j implements SydApi { RetWrap r = new RetWrap(); r.put("retCode", true); - if ( ( 0 != (be[0] ^ be[1]))) { + if ((0 != (be[0] ^ be[1]))) { r.put("retCode", false); r.put("msg", error.getInfo() == null || "".equals(error.getInfo()) ? RetWrap.transMsg(error.autoInt()) : error.getInfo()); @@ -992,6 +1046,15 @@ public class SydApi4j implements SydApi { } + //gc回收 + @Override + protected void finalize() throws Throwable { + super.finalize(); + if (null != this.socket) { + this.socket.close(); + } + } + /** * 确认链接可用 * 确认读缓存为空 @@ -1211,6 +1274,11 @@ public class SydApi4j implements SydApi { return this; } + @Override + public void init(SydApiBuilder builder) { + this.builder = builder; + } + @Override synchronized public SydApi connect(String ip, int port, String pwd, int connectTimeout, int readTimeout) { @@ -1970,6 +2038,50 @@ public class SydApi4j implements SydApi { return repackEncrypt(packet); } + @Override + public RetWrap generateDEByDn(byte[] dn, byte nAlg) { + Integer alg = new Integer(nAlg); + Proto6A proto = new Proto6A(); + // 填充数据 + PacketSN sn = PacketSN.gen(); + HashMap packet = new HashMap(); + packet.put("header", sn.getSn().array()); + HashMap data = new HashMap(); + data.put("alg$option", alg); + data.put("certificateModel$option", 1); + data.put("certificateDn", dn); + data.put("keyType", "X"); + packet.put("data", data); + // 渲染发送 耗时长 + ByteBuffer bb = proto.rend(packet); + synchronized (this) { + // 响应解析 + bb = syncRead(syncSend(bb)); + } + //ProtocolParser parser = pset.getProtocolResParse(); + Packet p = proto.parse(bb); + + Map ret = p.toMap(); + if ( + !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes()) + ) { + throw new SydApiException("包序号不匹配", -4); + } + ret = (Map) ret.get("data"); + PacketSection error = (PacketSection) ret.get("error"); + if (!"00".equals(error.getString())) { + throw new SydApiException(error.getInfo(), error.autoInt()); + } + RetWrap rw = new RetWrap(); + rw.put(SydApi.RET_CIPHER_KEY, ((PacketSection) ret.get("key")).getString()); + rw.put(SydApi.RET_SESSION_KEY, ((PacketSection) ret.get("lmkHead")).getString() + + ((PacketSection) ret.get("lmk")).getString() + ); + + rw.put(SydApi.RET_KCV, ((PacketSection) ret.get("keyCheck")).getString()); + + return rw; + } @Override public RetWrap generateDE(String certSerial, byte nAlg) { @@ -2449,6 +2561,7 @@ public class SydApi4j implements SydApi { return new byte[0]; } + // 测试通过 @Override public RetWrap genSymmetricKey(String keyType, char solution) { ProtoA0 proto = new ProtoA0(); @@ -2630,10 +2743,12 @@ public class SydApi4j implements SydApi { /** * 通过私钥获取公钥 - * @param userId 密钥对应的索引号 + * + * @param userId 密钥对应的索引号 * @param nKeyType * @return 公钥 */ + @Override public String SM2GetPublicKeyC_QX(int userId, int nKeyType) { //ProtocolRender render = pset.getProtocolReqRender("QQ"); @@ -2901,6 +3016,7 @@ public class SydApi4j implements SydApi { } + @Override public boolean SM2Verify( int nOrgDataType, byte[] publicKey, @@ -3229,15 +3345,15 @@ public class SydApi4j implements SydApi { Proto78 proto = new Proto78(); DTO78.Req req = new DTO78.Req() - .setHeader( PacketSN.gen().getSn().array() ) + .setHeader(PacketSN.gen().getSn().array()) .buildData() - .setAlgorithmKey( algBin ) - .setFillKey( DTO78.Req.Data.FillKeyOptions.OPVPKCS1v15填充方式.getBin() ) - .setPrivateKeyTag( SYMUtil.genPrivateKeyMark(userId, SYMUtil.KT_ENCRYPT, "00000001").getBytes() ) - .setInfoData( data ) + .setAlgorithmKey(algBin) + .setFillKey(DTO78.Req.Data.FillKeyOptions.OPVPKCS1v15填充方式.getBin()) + .setPrivateKeyTag(SYMUtil.genPrivateKeyMark(userId, SYMUtil.KT_ENCRYPT, "00000001").getBytes()) + .setInfoData(data) .closeBuilding(); - ByteBuffer bb = proto.rend( req.toSoup() ); + ByteBuffer bb = proto.rend(req.toSoup()); synchronized (this) { // 响应解析 bb = syncRead(syncSend(bb)); @@ -3245,9 +3361,9 @@ public class SydApi4j implements SydApi { Packet p = proto.parse(bb); DTO78.Res res = new DTO78.Res(); - res = res.fullFromSoup( proto.parse(bb).resSoup() ); + res = res.fullFromSoup(proto.parse(bb).resSoup()); - if ( "3030".equals(res.getData().getErrorAsHex()) ){ + if ("3030".equals(res.getData().getErrorAsHex())) { return res.getData().getDataAsBin(); } else { throw SydApiException.fromBin(res.getData().getErrorAsBin(), res.getData().getErrorCn()); @@ -3682,6 +3798,141 @@ public class SydApi4j implements SydApi { return rw; } + /** + * 生成数字信封 + * + * @param publicKey 公钥 + */ + @Override + public RetWrap genDigitalEnvelope(String publicKey) { + RetWrap retWrap = SM2GenSessionKey(publicKey); + return retWrap; + } + + /** + * 解密数字信封 + * + * @param sk 私钥索引 + * @param cipherKey 密文 + * @return sessionKey LMK加密下的密钥 + */ + @Override + public String deDigitalEnvelope(String sk, String cipherKey) { + RetWrap retWrap = SM2ConfirmSessionKeyC(sk, cipherKey); + return retWrap.get(SydApi.RET_SESSION_KEY).toString(); + } + + /** + * 数字信封加密数据 会员定制格式 + * @param keyValue 公钥值 + * @param inPutDataStr 报文明文 + * @param msgId 设备认证内容 + * @return 格式:sessionByPk(base64)+\r\n+头(base64)+\r\n+密文(base64) + * @throws UnsupportedEncodingException + */ + @Override + public String genDigitalEnvelopeWithDM(String keyValue, String inPutDataStr, String msgId) throws UnsupportedEncodingException { + String separator = "\r\n"; //分隔符 + byte[] inPutData = null; + if (null != builder) { + inPutData = inPutDataStr.getBytes(builder.getEncode()); + } else { + inPutData = inPutDataStr.getBytes(); + } + //生成数字信封 + RetWrap retWrap = genDigitalEnvelope(keyValue); + + //Hex格式sessionByPk:即公钥加密的密钥密文的 DER 编码 + String sessionByPk = retWrap.get(SydApi.RET_CIPHER_KEY).toString(); + //获取LMK加密下的密钥 + String sessionByLMK = retWrap.get(SydApi.RET_SESSION_KEY).toString(); + //数字信封加密数据 +// byte[] iv = "SHANGPIAOJIAOSUO".getBytes(); + //nAlg=1->0x8->SM4加密, roundmod=1 即轮模式为CBC,fullMode=1即填充模式为贪婪模式 + RetWrap retWrap1 = SYMEnDeData(true, 1, sessionByLMK, 1, 1, inPutData, null, 0); + byte[] ret = (byte[]) retWrap1.get("msg_all"); + + //拼接封装result + StringBuilder sb = new StringBuilder(); + sb.append(Util.encodeBase64(Util.hexString2Bytes(sessionByPk))); + sb.append(separator); + //TODO 补充头 + byte[] bytes = this.calcAuthHead(msgId.getBytes()); + sb.append(Util.encodeBase64(bytes)); + + sb.append(separator); + sb.append(Util.encodeBase64(ret)); + return sb.toString(); + } + + + @Override + public String genDigitalEnvelopeWithData(String keyValue, String inPutDataStr) throws UnsupportedEncodingException { + String separator = "\r\n"; //分隔符 + byte[] inPutData = null; + if (null != builder) { + inPutData = inPutDataStr.getBytes(builder.getEncode()); + } else { + inPutData = inPutDataStr.getBytes(); + } + + //生成数字信封 + // String pubKey =this.SM2GetPublicKeyC( index, 0 ); + RetWrap retWrap = genDigitalEnvelope(keyValue); + //Hex格式sessionByPk + String sessionByPk_HEX = retWrap.get(SydApi.RET_CIPHER_KEY).toString(); + + //HEX转BYTES +// byte[] sessionByPk = sessionByPk_HEX.getBytes(); + String sessionByLMK = retWrap.get(SydApi.RET_SESSION_KEY).toString(); + + //数字信封加密数据 + RetWrap retWrap1 = SYMEnDeData(true, 1, sessionByLMK, 1, 1, inPutData, null, 0); + byte[] ret = (byte[]) retWrap1.get("msg_all"); + + StringBuilder sb = new StringBuilder(); + sb.append(Util.encodeBase64(Util.hexString2Bytes(sessionByPk_HEX))); + sb.append(separator); + sb.append(Util.encodeBase64(ret)); + return sb.toString(); + } + + + @Override + public String deDigitalEnvelopeWithData(String sk, String inPutDataStr) throws UnsupportedEncodingException { + String str = "\r\n"; + String[] split = inPutDataStr.split(str); + + //截取数据 + //获取sessionByPk +// String sessionByPk= split[0]; + + byte[] bytes = Util.decodeBase64(split[0]); + // sessionByPk:即公钥加密的密钥密文的 DER 编码 + String sessionByPk = Util.bytes2HexString(bytes); + + //获取加密数据 +// byte[] data = Util.hexString2Bytes( split[split.length-1] ); + byte[] data = Util.decodeBase64(split[split.length - 1]); + + //解密数字信封,获取LMK加密下的密钥 + String sessionKeyByLMK = deDigitalEnvelope(sk, sessionByPk); + //解密数据 + //nAlg=1->0x9->SM4解密, roundmod=1 即轮模式为CBC,fullMode=1即填充模式为贪婪模式 + RetWrap retWrap = SYMEnDeData(false, 1, sessionKeyByLMK, 1, 1, data, null, 0); + if (null != builder) { + return new String((byte[]) retWrap.get("msg_all"), builder.getEncode()); + } + return new String((byte[]) retWrap.get("msg_all"), "UTF-8"); + } + + @Override + public String transKeyFromPkToLmk(String skIndex, String sessionKey) { + return "X12345678123456781234567812345678"; + } + + ; + @Override public RetWrap SM2ConfirmSessionKeyC(String userId, String cipherKey) { @@ -4037,14 +4288,14 @@ public class SydApi4j implements SydApi { /** * todo:通过密钥加密数据? - * @param alg 加密算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 + * + * @param alg 加密算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 * @param roundModel 密钥加密模式,1:ECB,2:CBC,3:CFB,4:OFB - * @param fullMode 填充模式,0:数据刚好是8的整数倍,不填充;1:在数据后面填充0x00,0x00…;2:在数据后填充0x80,0x00 … - * @param DEK DEK秘钥,如果源密钥为外部送入,则为LMK加密,否则为HSM用户密钥存储区。 - * @param infoData 数据 - * @param vector 初始向量数据,可选项,当加密模式为CBC,CFB或OFB时才显示此项 - * @return - * infoData: 密文数据 + * @param fullMode 填充模式,0:数据刚好是8的整数倍,不填充;1:在数据后面填充0x00,0x00…;2:在数据后填充0x80,0x00 … + * @param DEK DEK秘钥,如果源密钥为外部送入,则为LMK加密,否则为HSM用户密钥存储区。 + * @param infoData 数据 + * @param vector 初始向量数据,可选项,当加密模式为CBC,CFB或OFB时才显示此项 + * @return infoData: 密文数据 */ public byte[] Encrypt_Data(int alg, int roundModel, int fullMode, String DEK, byte[] infoData, byte[] vector) { ProtoQ1 proto = new ProtoQ1(); @@ -4108,12 +4359,13 @@ public class SydApi4j implements SydApi { /** * todo:解密数据 - * @param alg 解密算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 + * + * @param alg 解密算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 * @param roundModel 密钥解密模式,1:ECB,2:CBC,3:CFB,4:OFB - * @param fullMode 填充模式,0:数据刚好是8的整数倍,不填充;1:在数据后面填充0x00,0x00…;2:在数据后填充0x80,0x00 … - * @param DEK DEK秘钥,如果源密钥为外部送入,则为LMK加密,否则为HSM用户密钥存储区。 - * @param infoData 数据 - * @param vector 初始向量数据,可选项,当加密模式为CBC,CFB或OFB时才显示此项 + * @param fullMode 填充模式,0:数据刚好是8的整数倍,不填充;1:在数据后面填充0x00,0x00…;2:在数据后填充0x80,0x00 … + * @param DEK DEK秘钥,如果源密钥为外部送入,则为LMK加密,否则为HSM用户密钥存储区。 + * @param infoData 数据 + * @param vector 初始向量数据,可选项,当加密模式为CBC,CFB或OFB时才显示此项 * @return 解密后的明文数据 */ public byte[] Decrypt_Data(int alg, int roundModel, int fullMode, String DEK, byte[] infoData, byte[] vector) { @@ -4180,9 +4432,10 @@ public class SydApi4j implements SydApi { /** * 8.1生成一个MAC(=) + * * @param TAK * @param infoData MAC数据,数据长度应该为8的整数倍,如果不是8的整数倍,系统默认在数据后面填充0x00组成8的整数倍。 - * @param IV IV + * @param IV IV * @return 所计算出的MAC hex 格式 */ public byte[] MAC_Data(String TAK, String infoData, String IV) { @@ -4240,12 +4493,13 @@ public class SydApi4j implements SydApi { /** * 对大消息生成MAC(MAB)(PBOC3.0方式) - * @param mode 密钥长度:强填充0x80。0-单倍长度DES密钥,1-双倍长度DES密钥,2 – SM4 + * + * @param mode 密钥长度:强填充0x80。0-单倍长度DES密钥,1-双倍长度DES密钥,2 – SM4 * @param keyType 密钥类型:0-TAK(终端认证密钥)1-ZAK(区域认证密钥) - * @param key 密钥 - * @param odata MAC数据 - * @param block 消息块号,0:仅一块。1:第一块。2:中间块。3:最后块。 - * @param iv IV + * @param key 密钥 + * @param odata MAC数据 + * @param block 消息块号,0:仅一块。1:第一块。2:中间块。3:最后块。 + * @param iv IV * @return 所计算出的MAC */ public byte[] _calcPBOCMAC(int mode, int keyType, String key, byte[] odata, int block, byte[] iv) { @@ -4299,14 +4553,16 @@ public class SydApi4j implements SydApi { /** * 对大消息生成MAC(MAB)(PBOC3.0方式) - * @param mode 密钥长度:强填充0x80。0-单倍长度DES密钥,1-双倍长度DES密钥,2 – SM4 + * + * @param mode 密钥长度:强填充0x80。0-单倍长度DES密钥,1-双倍长度DES密钥,2 – SM4 * @param keyType 密钥类型:0-TAK(终端认证密钥)1-ZAK(区域认证密钥) - * @param key 密钥 - * @param data MAC数据 - * @param block 消息块号,0:仅一块。1:第一块。2:中间块。3:最后块。 - * @param iv IV + * @param key 密钥 + * @param data MAC数据 + * @param block 消息块号,0:仅一块。1:第一块。2:中间块。3:最后块。 + * @param iv IV * @return 所计算出的MAC */ + @Override public String calcPBOCMAC(int mode, int keyType, String key, byte[] data, int block, byte[] iv) { int packSize = 2048; @@ -4464,12 +4720,13 @@ public class SydApi4j implements SydApi { /** * mac 计算 * 校验一个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 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 AK 密钥 * @param infoData MAC数据 - * @param mac MAC值 hex 格式 + * @param mac MAC值 hex 格式 * @return */ public void MACCheck(int alg, int keyType, String AK, int fullMode, byte[] infoData, String mac) { @@ -4531,13 +4788,14 @@ public class SydApi4j implements SydApi { /** * 分散 - * @param mainKey LMK下加密的密钥 - * @param keyType 密钥类型,0: DEK,1: TAK - * @param disperseNum 指定对根密钥分散的次数(1-3次) - * @param dt 分散数据 - * @param disperseAlg 分散算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 + * + * @param mainKey LMK下加密的密钥 + * @param keyType 密钥类型,0: DEK,1: TAK + * @param disperseNum 指定对根密钥分散的次数(1-3次) + * @param dt 分散数据 + * @param disperseAlg 分散算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 * @param keyCheckType 密钥校验值类型,0:KCV 向后兼容,1:KCV 6H - * @return 密钥,被保护密钥lmk加密输出 + * @return 密钥, 被保护密钥lmk加密输出 */ public String SYD_Disperse(String mainKey, int keyType, int disperseNum, byte[] dt, int disperseAlg, int keyCheckType) { ProtoYA proto = new ProtoYA(); @@ -4605,6 +4863,7 @@ public class SydApi4j implements SydApi { return ((PacketSection) ret.get("lmk")).getString(); } + @Override public byte[] SYD_Encrypt_Data(int alg, String DEK, byte[] infoData, byte[] vector, int disperseAlg, byte[] factor) { String ss = SYD_Disperse(DEK, 0, 1, factor, disperseAlg, 0); byte[] bytes = Encrypt_Data(alg, 1, 2, ss, infoData, vector); @@ -4612,6 +4871,7 @@ public class SydApi4j implements SydApi { } + @Override public byte[] SYD_Decrypt_Data(int alg, String DEK, byte[] infoData, byte[] vector, int disperseAlg, byte[] factor) { String ss = SYD_Disperse(DEK, 0, 1, factor, disperseAlg, 0); byte[] bytes = Decrypt_Data(alg, 1, 2, ss, infoData, vector); @@ -4622,14 +4882,15 @@ public class SydApi4j implements SydApi { /** * 先锋定制特例-生成MAC * - * @param DEK LMK下加密的密钥 + * @param DEK LMK下加密的密钥 * @param infoData 生成MAC的数据 - * @param factor 分散数据 - * @param IV IV + * @param factor 分散数据 + * @param IV IV * @param disperseNum 指定对根密钥分散的次数(1-3次) * @param disperseAlg 分散算法,1:DES,2:3DES,3:IDEA,4:SM1,5:AES,6:SM4 * @return 所计算出的MAC hex 格式 */ + @Override public byte[] SYD_MAC_Data(String DEK, String infoData, byte[] factor, String IV, int disperseNum, int disperseAlg) { String ss = SYD_Disperse(DEK, 1, disperseNum, factor, disperseAlg, 0); @@ -4863,10 +5124,11 @@ public class SydApi4j implements SydApi { /** * 生成并打印一个成份 * 生成一个随机的成份,在与HSM相连接的打印机上打印出来并将加密值返回给主机 - * @param keyType 密钥类型 + * + * @param keyType 密钥类型 * @param solution 密钥方案(LMK)密钥长度/LMK 下加密密钥的方案 * @return RetWrap - * lmkKey lmk 头 + LMK 加密下的密钥。 + * lmkKey lmk 头 + LMK 加密下的密钥。 */ public RetWrap genAndPrint(String keyType, String solution) { ProtoA2 proto = new ProtoA2(); @@ -4922,6 +5184,7 @@ public class SydApi4j implements SydApi { /** * 打印 + * * @param format 打印格式 */ public void setPrintFormat(String format) { @@ -5148,14 +5411,16 @@ public class SydApi4j implements SydApi { /** * 生成一个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 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 maclen MAC数据长度,1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效) - * @param key 密钥 + * @param maclen MAC数据长度,1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效) + * @param key 密钥 * @param infoData MAC数据 * @return mac 值 */ + @Override public byte[] MACCalc(int alg, int keyType, int fullmode, int maclen, String key, byte[] infoData) { ProtoMA proto = new ProtoMA(); @@ -5214,11 +5479,12 @@ public class SydApi4j implements SydApi { /** * 转换秘钥方案,转换一个现有的密钥到一个新的密钥方案。这个命令支持从32H,X和Y格式转换 - * @param keyType 秘钥类型 - * @param key LMK 加密下的密钥。 + * + * @param keyType 秘钥类型 + * @param key LMK 加密下的密钥。 * @param solution 密钥长度/LMK 下加密密钥的方案 * @return RetWrap - * lmkkey lmk 头 + LMK 加密下的密钥。 + * lmkkey lmk 头 + LMK 加密下的密钥。 */ public RetWrap conversionKey(String keyType, String key, char solution) { @@ -5273,10 +5539,10 @@ public class SydApi4j implements SydApi { /** * 将ZMK由ZMK转为LMK加密(+) + * * @param zmki LMK 对(04-05)下加密的 ZMKi - * @param zmk ZMKi 下加密的 ZMK - * @return - * zmkKey: ZMK 加密下的ZPK + * @param zmk ZMKi 下加密的 ZMK + * @return zmkKey: ZMK 加密下的ZPK * keyCheck: 密钥校验值。 */ public RetWrap changZMK2LMK(String zmki, String zmk) { @@ -5330,13 +5596,14 @@ public class SydApi4j implements SydApi { /** * 获取加密机设备信息 + * * @param num 授权响应码 - * @return - * NAME: 设备生产厂商名称 - * MODEL: 设备型号 - * EQUIPNO: 设备机具号 - * SOFTVERSION: 设备内部软件版本号 + * @return NAME: 设备生产厂商名称 + * MODEL: 设备型号 + * EQUIPNO: 设备机具号 + * SOFTVERSION: 设备内部软件版本号 */ + @Override public RetWrap getVersion(String num) { ProtoHV proto = new ProtoHV(); @@ -5380,15 +5647,15 @@ public class SydApi4j implements SydApi { /** * 22.1计算HASH散列值(HMAC-MD5\SHA1\SHA256)(+) ->高性能支持 ,test暂未通过 - * @param key 秘钥数据 - * @param hashType HASH类型,指示用于哈希证书数据的哈希算法的类型.1 - SHA1, 2 - SHA256, 3 - SHA384, 4 - SHA512, 5 - SM3 + * + * @param key 秘钥数据 + * @param hashType HASH类型,指示用于哈希证书数据的哈希算法的类型.1 - SHA1, 2 - SHA256, 3 - SHA384, 4 - SHA512, 5 - SM3 * @param contextInfo 输入的散列上下文信息,加密机输出,原文传入 - * @param infoData 二进制的消息块 - * @return - * contextInfo_Length: 上下文信息长度 - * contextInfo: 上下文信息 - * HMAC_LEN: HMAC结果长度 - * HAMC: HMAC结果 + * @param infoData 二进制的消息块 + * @return contextInfo_Length: 上下文信息长度 + * contextInfo: 上下文信息 + * HMAC_LEN: HMAC结果长度 + * HAMC: HMAC结果 */ public RetWrap calcHash(String key, int hashType, String contextInfo, byte[] infoData) { Proto82 proto = new Proto82(); @@ -5434,13 +5701,13 @@ public class SydApi4j implements SydApi { /** * 19.1解密数据并由公钥加密输出 ->: code = 19 ( 0x13 ) msg = 数据解密错(C3) (服务器代码问题) - * @param DEK DEK,LMK对(36-37)下加密的DEK。 - * @param infoData 密文数据 - * @param alg 算法标识,0:RSA 1:SM2 + * + * @param DEK DEK,LMK对(36-37)下加密的DEK。 + * @param infoData 密文数据 + * @param alg 算法标识,0:RSA 1:SM2 * @param publicKey 公钥的DER编码 - * @return - * keyLen: 公钥加密的密文长度 - * key: 公钥加密的密文的DER编码 + * @return keyLen: 公钥加密的密文长度 + * key: 公钥加密的密文的DER编码 */ public RetWrap decryptAndEncryptByP(String DEK, byte[] infoData, int alg, byte[] publicKey) { // 获取协议 @@ -5491,12 +5758,12 @@ public class SydApi4j implements SydApi { /** * 19.2由私钥解密密文数据并经过DEK加密后输出 ->code = 21 ( 0x15 ) msg = 输入的数据格式错误,等待19.1解决 - * @param DEK DEK,LMK对(36-37)下加密的DEK。 - * @param infoData 公钥加密的密文的DER编码 + * + * @param DEK DEK,LMK对(36-37)下加密的DEK。 + * @param infoData 公钥加密的密文的DER编码 * @param privatekey LMK加密的私钥 - * @return - * keyLen: 密文数据的字节长度 - * key: 密文数据 + * @return keyLen: 密文数据的字节长度 + * key: 密文数据 */ public RetWrap decryptAndEncryptByS(String DEK, byte[] infoData, String privatekey) { // 获取协议 @@ -5547,11 +5814,11 @@ public class SydApi4j implements SydApi { /** * 18.1加押指令(+) -> pass - * @param keyType 秘钥类型 - * @param key LMK加密下的应用密钥 + * + * @param keyType 秘钥类型 + * @param key LMK加密下的应用密钥 * @param infoData 加押数据 - * @return - * MAC: 密押,默认为8H + * @return MAC: 密押,默认为8H */ public RetWrap impose(String keyType, String key, byte[] infoData) { // 获取协议 @@ -5598,9 +5865,10 @@ public class SydApi4j implements SydApi { /** * 18.2核押指令(+) -> pass - * @param keyType 密钥类型 - * @param key LMK加密下的应用密钥 - * @param secret 需要验证的密押 + * + * @param keyType 密钥类型 + * @param key LMK加密下的应用密钥 + * @param secret 需要验证的密押 * @param infoData 加押数据 * @return 是否正确 */ @@ -5648,12 +5916,12 @@ public class SydApi4j implements SydApi { /** * 18.3加解密指令(+) -> pass - * @param keyType 密钥类型 - * @param key LMK加密下的应用密钥 + * + * @param keyType 密钥类型 + * @param key LMK加密下的应用密钥 * @param infoData 信息数据 - * @return - * infoLen: 返回原数据长度 - * info: 信息数据 + * @return infoLen: 返回原数据长度 + * info: 信息数据 */ public RetWrap encryAndDecry(String keyType, String key, byte[] infoData) { // 获取协议 @@ -5702,13 +5970,13 @@ public class SydApi4j implements SydApi { /** * 18.4转加密指令(+) -> pass - * @param keyType 密钥类型 - * @param srcKey 源应用秘钥,LMK加密下的应用密钥 - * @param aimKey 目的应用秘钥,LMK加密下的应用密钥 + * + * @param keyType 密钥类型 + * @param srcKey 源应用秘钥,LMK加密下的应用密钥 + * @param aimKey 目的应用秘钥,LMK加密下的应用密钥 * @param infoData 密文数据 - * @return - * infoLen: 密文数据长度 - * info: 密文数据 + * @return infoLen: 密文数据长度 + * info: 密文数据 */ public RetWrap switchEncry(String keyType, String srcKey, String aimKey, byte[] infoData) { // 获取协议 @@ -5756,6 +6024,7 @@ public class SydApi4j implements SydApi { /** * 18.5 PIN加解密指令(+) -> pass + * * @param key LMK(06-07)加密下的ZPK * @param pin PIN数据 * @return PIN数据 @@ -5803,8 +6072,9 @@ public class SydApi4j implements SydApi { /** * 18.6 PIN转加密指令(+) -> pass - * @param srcKey 源ZPK,LMK(06-07)加密下的ZPK - * @param aimKey 目的ZPK,LMK(06-07)加密下的ZPK + * + * @param srcKey 源ZPK,LMK(06-07)加密下的ZPK + * @param aimKey 目的ZPK,LMK(06-07)加密下的ZPK * @param infoData 密文PIN * @return 密文PIN */ @@ -5851,9 +6121,9 @@ public class SydApi4j implements SydApi { /** * 17.8 获取传输保护密钥(+) -> code = 18 ( 0x12 ) msg = 未定义的错误 - * @return - * DK: LMK14-15 加密下的密钥 - * keyCheck: 密钥校验值 + * + * @return DK: LMK14-15 加密下的密钥 + * keyCheck: 密钥校验值 */ public RetWrap getTransmissionKey() { // 获取协议 @@ -5893,11 +6163,11 @@ public class SydApi4j implements SydApi { /** * 16.7 LMK加密密钥转公钥加密输出 ->pass - * @param pk 公钥 + * + * @param pk 公钥 * @param key LMK30-31下加密的密钥 - * @return - * keyLength: 公钥加密的密文长度 - * key: 公钥加密的密文的DER编码 + * @return keyLength: 公钥加密的密文长度 + * key: 公钥加密的密文的DER编码 */ public RetWrap LMK2SM2(byte[] pk, String key) { // 获取协议 @@ -5941,11 +6211,11 @@ public class SydApi4j implements SydApi { /** * 16.8 ECC密钥生成 -> code = 129 ( 0x81 ) msg = 未定义的错误 (服务器代码问题) - * @param nid 曲线nid + * + * @param nid 曲线nid * @param index 索引 - * @return - * PublicKey: 公钥的 DER 编码 - * PrivateKey: LMK 加密下的私钥(LMK34-35) + * @return PublicKey: 公钥的 DER 编码 + * PrivateKey: LMK 加密下的私钥(LMK34-35) */ public RetWrap genKeyPair(int nid, int index) { //ProtocolRender render = pset.getProtocolReqRender("E2"); @@ -5998,13 +6268,13 @@ public class SydApi4j implements SydApi { /** * 15.7计算HASH散列值(MD5\SHA1\SHA256)(+) -> pass - * @param hashType HASH类型。0: SHA1,1: SHA256,2: MD5 - * @param packSn 消息块号。0=仅一块,1=第一块,2=中间块,3=最后块 - * @param msg 二进制的消息块 + * + * @param hashType HASH类型。0: SHA1,1: SHA256,2: MD5 + * @param packSn 消息块号。0=仅一块,1=第一块,2=中间块,3=最后块 + * @param msg 二进制的消息块 * @param filterData 过渡消息数据,只对“消息块号”为 2、3 时有效 - * @return - * filterData: 过渡消息数据.只对“消息块号”为 2、1 时有效 - * hash: hash + * @return filterData: 过渡消息数据.只对“消息块号”为 2、1 时有效 + * hash: hash */ public RetWrap conutHash(int hashType, int packSn, byte[] msg, byte[] filterData) { Proto7D proto = new Proto7D(); @@ -6048,8 +6318,9 @@ public class SydApi4j implements SydApi { /** * 10.1装载对称密钥至用户存储区(=) -> pass - * @param index 索引地址,指示用户密钥存储区的27位地址。 - * @param key 被加密的密钥 + * + * @param index 索引地址,指示用户密钥存储区的27位地址。 + * @param key 被加密的密钥 * @param checkValue 校验值 * @return 是否成功 */ @@ -6104,11 +6375,12 @@ public class SydApi4j implements SydApi { /** * 10.2从用户存储区读取对称密钥(=) -> pass(秘钥校验值暂时无法获取) + * * @param index 索引地址,指示用户密钥存储区的27位地址 - * @return - * key: 被加密的密钥 + * @return key: 被加密的密钥 */ - public RetWrap readKey(String index) { + @Override + public String readKey(String index) { ProtoLF proto = new ProtoLF(); HashMap packet = new HashMap(); HashMap data = new HashMap(); @@ -6142,17 +6414,18 @@ public class SydApi4j implements SydApi { byte[] bs = new byte[keys.length + keyHeads.length]; System.arraycopy(keyHeads, 0, bs, 0, keyHeads.length); System.arraycopy(keys, 0, bs, keyHeads.length, keys.length); - rw.put("key", bs); +// rw.put("key", bs); //rw.put("keyCheck", ((PacketSection) ret.get("keyCheck")).getBytes()); - return rw; + return new String(bs); //返回HEX格式 } } } /** * 10.3更新对称密钥至用户存储区(=) -> pass - * @param index 索引地址,指示用户密钥存储区的27位地址 - * @param key 被加密的密钥 + * + * @param index 索引地址,指示用户密钥存储区的27位地址 + * @param key 被加密的密钥 * @param checkValue 校验值 * @return */ @@ -6214,15 +6487,16 @@ public class SydApi4j implements SydApi { /** * 数据转加密指令(Y0)(=) -> pass (注:密文数据那项不一定需要传加密出来的数据) - * @param srcType 源密钥类型 - * @param sca 源算法SCA + * + * @param srcType 源密钥类型 + * @param sca 源算法SCA * @param desKeyType 目的秘钥类型 - * @param dca 目的算法SCA + * @param dca 目的算法SCA * @param roundModel 加密模式 - * @param sDEK 源秘钥DEK - * @param dDEK 目的秘钥DEK - * @param infoData 密文数据 - * @param vector 向量 + * @param sDEK 源秘钥DEK + * @param dDEK 目的秘钥DEK + * @param infoData 密文数据 + * @param vector 向量 * @return byte[] 目的密钥加密的密文数据 */ public byte[] switchEncryY(String srcType, int sca, String desKeyType, int dca, int roundModel, String sDEK, String dDEK, byte[] infoData, String vector) { @@ -6269,14 +6543,14 @@ public class SydApi4j implements SydApi { /** * 8.3用对大消息生成MAC(MAB)(*) -> pass - * @param packSn 消息块号,0:仅一块。1:第一块。2:中间块。3:最后块。 + * + * @param packSn 消息块号,0:仅一块。1:第一块。2:中间块。3:最后块。 * @param keyType 密钥类型:0-TAK(终端认证密钥)1-ZAK(区域认证密钥) - * @param mode 密钥长度:0-单倍长度DES密钥.Ansi X9.9, 1-双倍长度DES密钥,Ansi X9.19, 2 – SM4-CBC,弱填充0x00,银联, 3—3DES-CBC, ,弱填充0x00,银联 - * @param key 密钥 - * @param iv IV - * @param msg 消息块 - * @return - * MAB: 当消息块号为“1”或“2”时,作为下一块的IV。当消息块号为“0”或“3”时,用于消息认证。 + * @param mode 密钥长度:0-单倍长度DES密钥.Ansi X9.9, 1-双倍长度DES密钥,Ansi X9.19, 2 – SM4-CBC,弱填充0x00,银联, 3—3DES-CBC, ,弱填充0x00,银联 + * @param key 密钥 + * @param iv IV + * @param msg 消息块 + * @return MAB: 当消息块号为“1”或“2”时,作为下一块的IV。当消息块号为“0”或“3”时,用于消息认证。 */ public RetWrap genMAB(int packSn, int keyType, int mode, String key, byte[] iv, byte[] msg) { ProtoMS proto = new ProtoMS(); @@ -6322,6 +6596,7 @@ public class SydApi4j implements SydApi { /** * 7.1生成一个随机的PIN(=) -> pass 不能传算法标识和加密算法这两项,否则报错 + * * @param account 账号中去除校验位的最右 12 位 * @return LMK 对(02-03)下加密的导出 PINBLOCK。(PINBLOCK格式默认为 01 格式) */ @@ -6362,10 +6637,11 @@ public class SydApi4j implements SydApi { /** * 7.2解密PINBLOCK, 并打印PIN 明文(=) -> : code = -2 ( 0xfffffffe ) msg = 接收数据超时 - * @param fileType 文档类型 A:“two-up”格式中的第一个信封。B:“two-up”格式中的第二个信封。C:1步格式。 - * @param account 账号,账号中去除校验位的最右 12 位 + * + * @param fileType 文档类型 A:“two-up”格式中的第一个信封。B:“two-up”格式中的第二个信封。C:1步格式。 + * @param account 账号,账号中去除校验位的最右 12 位 * @param encryptionAlg 加密算法 0:DES, 1:3DES(默认), 2:SM4 - * @param pinBlock PIN 块,LMK 对(02-03)下加密的导出 PINBLOCK。(PINBLOCK格式默认为 01 格式) + * @param pinBlock PIN 块,LMK 对(02-03)下加密的导出 PINBLOCK。(PINBLOCK格式默认为 01 格式) * @return */ public Boolean decryPINBAndPrint(char fileType, String account, int encryptionAlg, String pinBlock) { @@ -6418,13 +6694,14 @@ public class SydApi4j implements SydApi { /** * 7.3将PINBLOCK从一个ZPK翻译到另一个ZPK(*) -> ->pass - * @param zpk1 源 ZPK,当前加密 PIN 块的 ZPK - * @param zpk2 目的 ZPK,将要加密 PIN 块的 ZPK;LMK 对(06-07)下加密 - * @param sca 源算法 SCA,1:3DES, 2:SM4 - * @param dca 目的算法DCA, 1:3DES, 2:SM4 + * + * @param zpk1 源 ZPK,当前加密 PIN 块的 ZPK + * @param zpk2 目的 ZPK,将要加密 PIN 块的 ZPK;LMK 对(06-07)下加密 + * @param sca 源算法 SCA,1:3DES, 2:SM4 + * @param dca 目的算法DCA, 1:3DES, 2:SM4 * @param spt * @param dpt - * @param pin 源 PIN 块,源 ZPK 下加密的源 PIN 块 + * @param pin 源 PIN 块,源 ZPK 下加密的源 PIN 块 * @param account 账号中去除校验位的最右 12 位 * @return 目的 ZPK 下加密的目的 PIN 块 */ @@ -6482,11 +6759,12 @@ public class SydApi4j implements SydApi { /** * 7.4将PINBLOCK从ZPK翻译到LMK(*) ->pass - * @param zpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密 - * @param sca 源算法 SCA,1:3DES, 2:SM4 - * @param dca 目的算法DCA, 1:3DES, 2:SM4 - * @param pt PIN 块格式,源 PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R06:不带主帐号的 ANSI9.8 格式 - * @param pin 源 ZPK 下加密的源 PIN 块 + * + * @param zpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密 + * @param sca 源算法 SCA,1:3DES, 2:SM4 + * @param dca 目的算法DCA, 1:3DES, 2:SM4 + * @param pt PIN 块格式,源 PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R06:不带主帐号的 ANSI9.8 格式 + * @param pin 源 ZPK 下加密的源 PIN 块 * @param account 账号中去除校验位的最右 12 位 * @return PIN 块,LMK 对(02-03)下加密的 PIN */ @@ -6539,11 +6817,12 @@ public class SydApi4j implements SydApi { /** * 7.5将PINBLOCK从LMK翻译到ZPK(*) ->pass - * @param zpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密 - * @param sca 源算法 SCA,1:3DES, 2:SM4 - * @param dca 目的算法DCA, 1:3DES, 2:SM4 - * @param pt PIN 块格式,源 PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R06:不带主帐号的 ANSI9.8 格式 - * @param pin 源 ZPK 下加密的源 PIN 块 + * + * @param zpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密 + * @param sca 源算法 SCA,1:3DES, 2:SM4 + * @param dca 目的算法DCA, 1:3DES, 2:SM4 + * @param pt PIN 块格式,源 PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R06:不带主帐号的 ANSI9.8 格式 + * @param pin 源 ZPK 下加密的源 PIN 块 * @param account 账号中去除校验位的最右 12 位 * @return PIN 块,LMK 对(02-03)下加密的 PIN */ @@ -6596,13 +6875,14 @@ public class SydApi4j implements SydApi { /** * 7.6将PINBLOCK从TPK翻译到ZPK(=) -> pass - * @param tpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密。 - * @param zpk 将要加密 PIN 块的 ZPK;LMK 对(06-07)下加密。 - * @param sca 源算法 SCA,1:3DES(默认), 2:SM4 - * @param dca 目的算法DCA, 1:3DES(默认), 2:SM4 - * @param spt 源PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R; 06:不带主帐号的 ANSI9.8 格式 - * @param dpt 目的 PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R; 06:不带主帐号的 ANSI9.8 格式 - * @param pin 源 ZPK 下加密的源 PIN 块 + * + * @param tpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密。 + * @param zpk 将要加密 PIN 块的 ZPK;LMK 对(06-07)下加密。 + * @param sca 源算法 SCA,1:3DES(默认), 2:SM4 + * @param dca 目的算法DCA, 1:3DES(默认), 2:SM4 + * @param spt 源PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R; 06:不带主帐号的 ANSI9.8 格式 + * @param dpt 目的 PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R; 06:不带主帐号的 ANSI9.8 格式 + * @param pin 源 ZPK 下加密的源 PIN 块 * @param account 账号中去除校验位的最右 12 位 * @return 目的 ZPK 下加密的目的 PIN 块 */ @@ -6657,11 +6937,12 @@ public class SydApi4j implements SydApi { /** * 7.7将PINBLOCK从TPK翻译到LMK(=) -> pass - * @param zpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密。 - * @param sca 源算法 SCA,1:3DES(默认), 2:SM4 - * @param dca 目的算法DCA, 1:3DES(默认), 2:SM4 - * @param pt 源PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R; 06:不带主帐号的 ANSI9.8 格式 - * @param pin 源 ZPK 下加密的源 PIN 块 + * + * @param zpk 当前加密 PIN 块的 ZPK;LMK 对(06-07)下加密。 + * @param sca 源算法 SCA,1:3DES(默认), 2:SM4 + * @param dca 目的算法DCA, 1:3DES(默认), 2:SM4 + * @param pt 源PIN 块的格式代码。01:带主帐号的 ANSI9.8 格式; 02: Docutel ATM;03: Diebold and IBM ATM,;04: Plus Network;05: ISO9564-1-1 格式,1NP..PR...R; 06:不带主帐号的 ANSI9.8 格式 + * @param pin 源 ZPK 下加密的源 PIN 块 * @param account 账号中去除校验位的最右 12 位 * @return LMK 对(02-03)下加密的 PIN */ @@ -6714,8 +6995,9 @@ public class SydApi4j implements SydApi { /** * 7.8加密一个明文的PIN(*) -> pass - * @param alg 算法标识,0:3DES,1:SM4 - * @param pin 左对齐的形式的文本PIN,后面附加字符“X’F”直至已加密PIN的长度。其值在安全配置“CS”命令中设置(范围为5至13)。例如:PIN:123456,此字段应该为06123456FFFFFFFF(8字节分组算法) + * + * @param alg 算法标识,0:3DES,1:SM4 + * @param pin 左对齐的形式的文本PIN,后面附加字符“X’F”直至已加密PIN的长度。其值在安全配置“CS”命令中设置(范围为5至13)。例如:PIN:123456,此字段应该为06123456FFFFFFFF(8字节分组算法) * @param account 账号中去除校验位的最右12位 * @return LMK 对(02-03)下加密的 PIN */ @@ -6764,9 +7046,10 @@ public class SydApi4j implements SydApi { /** * 7.9解密一个已加密的PIN(*) -> 只解出原PIn,缺少参考数这一项 - * @param alg 算法标识,0:3DES,1:SM4 + * + * @param alg 算法标识,0:3DES,1:SM4 * @param PINBLOCK LMK对(02-03)下加密的PIN。 - * @param account 账号中去除校验位的最右12位。 + * @param account 账号中去除校验位的最右12位。 * @return PIN */ public String decryPIN(int alg, String PINBLOCK, String account) { @@ -6814,15 +7097,16 @@ public class SydApi4j implements SydApi { /** * 7.10将PINBLOCK从一个密钥翻译到另一个密钥 -> pass - * @param srcKeyType 源秘钥类型(查看密钥类型表) - * @param desKeyType 目的秘钥类型(查看密钥类型表) - * @param srcKey 源秘钥,当前加密PIN块的密钥;LMK加密的密文 - * @param desKey 目的秘钥,将要加密PIN块的密钥;LMK加密的密文 - * @param sca 源算法SCA,1:3DES,2:SM4 - * @param dca 目的算法DCA, 1:3DES,2:SM4 - * @param sPin 源PIN块, 源密钥加密的源PIN块,源算法3DES时16H,源算法SM4时32H。 + * + * @param srcKeyType 源秘钥类型(查看密钥类型表) + * @param desKeyType 目的秘钥类型(查看密钥类型表) + * @param srcKey 源秘钥,当前加密PIN块的密钥;LMK加密的密文 + * @param desKey 目的秘钥,将要加密PIN块的密钥;LMK加密的密文 + * @param sca 源算法SCA,1:3DES,2:SM4 + * @param dca 目的算法DCA, 1:3DES,2:SM4 + * @param sPin 源PIN块, 源密钥加密的源PIN块,源算法3DES时16H,源算法SM4时32H。 * @param primaryAccount 主账号,账号中去除校验位的最右12位。 - * @return 目的PIN块,目的秘钥下加密的目的PIN块 + * @return 目的PIN块, 目的秘钥下加密的目的PIN块 */ public String transPinFrOneKeyToAno(String srcKeyType, String desKeyType, String srcKey, String desKey, int sca, int dca, String sPin, String primaryAccount) { ProtoCB proto = new ProtoCB(); @@ -6870,11 +7154,11 @@ public class SydApi4j implements SydApi { /** * 6.1生成一个TAK(=) -> pass * 生成一个随机的密钥,然后在TMK(TPK或PVK)和LMK对16-17下加密 + * * @param tmk LMK 对(14-15)下加密的 TMK - * @return - * lmkKey: LMK 对 16-17 下加密的密钥 - * tmkKey: TMK 下加密的随机的 TAK - * keyCheck: 密钥校验值 + * @return lmkKey: LMK 对 16-17 下加密的密钥 + * tmkKey: TMK 下加密的随机的 TAK + * keyCheck: 密钥校验值 */ public RetWrap genTAK(String tmk) { ProtoHA proto = new ProtoHA(); @@ -6931,11 +7215,11 @@ public class SydApi4j implements SydApi { /** * 6.2将TAK从ZMK转为LMK加密(=) -> PASS + * * @param zmk LMK 对(04-05)下加密的 ZMK * @param tak ZMK 下加密的 TAK - * @return - * lmkKey: LMK 对 16-17 下加密的 TAK - * keyCheck: 密钥校验值 + * @return lmkKey: LMK 对 16-17 下加密的 TAK + * keyCheck: 密钥校验值 */ public RetWrap transTAKFromZMKToLMK(String zmk, String tak) { ProtoMF proto = new ProtoMF(); @@ -6985,11 +7269,11 @@ public class SydApi4j implements SydApi { /** * 6.3将TAK从LMK转为ZMK加密(=) -> PASS + * * @param zmk LMK 对(04-05)下加密的 ZMK * @param tak LMK 对(16-17)下加密的 TAK - * @return - * zmkKey: ZMK 下加密的 TAK - * keyCheck: 密钥校验值 + * @return zmkKey: ZMK 下加密的 TAK + * keyCheck: 密钥校验值 */ public RetWrap transTAKFromLMKToZMK(String zmk, String tak) { ProtoMG proto = new ProtoMG(); @@ -7039,11 +7323,11 @@ public class SydApi4j implements SydApi { /** * 6.4将TAK从LMK转为TMK加密(=) -> PASS + * * @param tmk LMK 对(14-15)下加密的 TMK * @param tak LMK 对(16-17)下加密的 TAK - * @return - * tmkKey: 转换后的 TAK;TMK 下加密 - * keyCheck: 密钥校验值 + * @return tmkKey: 转换后的 TAK;TMK 下加密 + * keyCheck: 密钥校验值 */ public RetWrap transTAKFromLMKToTMK(String tmk, String tak) { ProtoAG proto = new ProtoAG(); @@ -7094,11 +7378,11 @@ public class SydApi4j implements SydApi { /** * 5.1生成一个TMK、TPK或PVK加密下的新密钥(=) -> PASS + * * @param tmk LMK 对(14-15)下加密的 TMK、TPK 或 PVK - * @return - * lmkKey: LMK下加密的新密钥 - * tmkKey: 当前的TMK (TPK或PVK)下加密的新密钥 - * keyCheck: 密钥校验值 + * @return lmkKey: LMK下加密的新密钥 + * tmkKey: 当前的TMK (TPK或PVK)下加密的新密钥 + * keyCheck: 密钥校验值 */ public RetWrap genKeyByTMKOrTPKOrPVK(String tmk) { ProtoHC proto = new ProtoHC(); @@ -7157,11 +7441,11 @@ public class SydApi4j implements SydApi { /** * 5.2将TMK、TPK或PVK从LMK转为另一TMK、TPK或PVK加密(+) * 将TMK、TPK或PVK从LMK对(14-15)下转为另一TMK、TPK或PVK下加密 - * @param tmkNow LMK 对(14-15)下加密的当前 TMK、 TPK 或 PVK + * + * @param tmkNow LMK 对(14-15)下加密的当前 TMK、 TPK 或 PVK * @param tmkStorage LMK 对(14-15)下加密的存储 TMK、 TPK 或 PVK - * @return - * tmkKey: 当前密钥下加密的存储密钥 - * keyCheck: 密钥校验值 + * @return tmkKey: 当前密钥下加密的存储密钥 + * keyCheck: 密钥校验值 */ public RetWrap tranKeyByTMKToAno(String tmkNow, String tmkStorage) { ProtoAE proto = new ProtoAE(); @@ -7211,11 +7495,11 @@ public class SydApi4j implements SydApi { /** * 5.3将TMK、TPK或PVK从ZMK转为LMK加密(=) -> PASS + * * @param zmk LMK 对(04-05)下加密的 ZMK * @param tmk ZMK 下加密的 TMK、 TPK 或 PVK - * @return - * tmkKey: 当前密钥下加密的存储密钥 - * keyCheck: 密钥校验值。 + * @return tmkKey: 当前密钥下加密的存储密钥 + * keyCheck: 密钥校验值。 */ public RetWrap tranKeyByTMKFromZMKToLMK(String zmk, String tmk) { ProtoFC proto = new ProtoFC(); @@ -7266,11 +7550,11 @@ public class SydApi4j implements SydApi { /** * 5.4将TMK、TPK或PVK从LMK转为ZMK加密(=) -> PASS + * * @param zmk LMK 对(04-05)下加密的 ZMK * @param tmk LMK 对(14-15)下加密的 TMK、TPK 或 PVK - * @return - * tmkKey: 当前密钥下加密的存储密钥 - * keyCheck: 密钥校验值 + * @return tmkKey: 当前密钥下加密的存储密钥 + * keyCheck: 密钥校验值 */ public RetWrap tranKeyByTMKFromLMKToZMK(String zmk, String tmk) { ProtoFE proto = new ProtoFE(); @@ -7321,12 +7605,12 @@ public class SydApi4j implements SydApi { /** * 生成一个ZEK或ZAK + * * @param key 标识 0为ZEK,1为ZAK。 * @param zmk LMK 对(04-05)加密的 ZMK - * @return - * lmkKey: 转换后的 ZPK - * zmkKey: 转换后的 ZPK - * keyCheck: 密钥校验值。 + * @return lmkKey: 转换后的 ZPK + * zmkKey: 转换后的 ZPK + * keyCheck: 密钥校验值。 */ public RetWrap genZEKOrZAK(int key, String zmk) { ProtoFI proto = new ProtoFI(); @@ -7401,12 +7685,12 @@ public class SydApi4j implements SydApi { /** * 4.2将ZEK/ZAK从ZMK转为LMK加密(=) -> pass - * @param key 标识 0为ZEK,1为ZAK - * @param zmk LMK 对(04-05)加密的 ZMK + * + * @param key 标识 0为ZEK,1为ZAK + * @param zmk LMK 对(04-05)加密的 ZMK * @param zekOrzak ZMK 下加密的 ZEK 或 ZAK - * @return - * lmkKey: 当标志位为1时为LMK26-27对下加密的ZAK,当标志位为0时为LMK30-31对下加密的ZEK。 - * keyCheck: 密钥校验值。 + * @return lmkKey: 当标志位为1时为LMK26-27对下加密的ZAK,当标志位为0时为LMK30-31对下加密的ZEK。 + * keyCheck: 密钥校验值。 */ public RetWrap tranZEAKFromZMKToLMK(int key, String zmk, String zekOrzak) { ProtoFK proto = new ProtoFK(); @@ -7467,12 +7751,12 @@ public class SydApi4j implements SydApi { /** * 4.3将ZEK/ZAK从LMK转为ZMK加密(=) -> pass - * @param key 标识 0为ZEK,1为ZAK - * @param zmk LMK 对(04-05)加密的 ZMK + * + * @param key 标识 0为ZEK,1为ZAK + * @param zmk LMK 对(04-05)加密的 ZMK * @param zekOrzak ZMK 下加密的 ZEK 或 ZAK,标志位为 0 时为 ZEK,1 为 ZAK - * @return - * zmkKey: 转换后的 ZPK。 - * keyCheck: 密钥校验值。 + * @return zmkKey: 转换后的 ZPK。 + * keyCheck: 密钥校验值。 */ public RetWrap tranZEAKFromLMKToZMK(int key, String zmk, String zekOrzak) { ProtoFM proto = new ProtoFM(); @@ -7534,10 +7818,10 @@ public class SydApi4j implements SydApi { /** * 3.1生成一个ZPK(=) * 生成一个随机的ZPK,同时返回主机为传输给另一群体的而由ZMK加密的ZPK和为存储在主机数据库中而由LMK加密的ZPK + * * @param zmk LMK对(04-05)加密的ZMK。 - * @return - * zmkKey: zmk 头 + ZMK 加密下的ZPK。 - * keyCheck: 密钥校验值 + * @return zmkKey: zmk 头 + ZMK 加密下的ZPK。 + * keyCheck: 密钥校验值 */ public RetWrap genZPK(String zmk) { ProtoIA proto = new ProtoIA(); @@ -7596,11 +7880,11 @@ public class SydApi4j implements SydApi { /** * 3.2将ZPK由ZMK转为LMK加密(=) + * * @param zmk LMK 对(04-05)加密的 ZMK。 * @param zpk ZMK 下加密的 ZPK - * @return - * zpkKey: 转换后的 ZPK;由 LMK06-07 对加密 - * keyCheck: 密钥校验值 + * @return zpkKey: 转换后的 ZPK;由 LMK06-07 对加密 + * keyCheck: 密钥校验值 */ public RetWrap tranZPKFromZMKToLMK(String zmk, String zpk) { ProtoFA proto = new ProtoFA(); @@ -7652,11 +7936,11 @@ public class SydApi4j implements SydApi { /** * 3.3将ZPK由LMK转为ZMK加密 -> pass + * * @param zmk LMK 对(04-05)加密的 ZMK * @param zpk LMK 对(06-07)下加密的 ZPK - * @return - * zpkKey: 转换后的 ZPK; - * keyCheck: 密钥校验值 + * @return zpkKey: 转换后的 ZPK; + * keyCheck: 密钥校验值 */ public RetWrap tranZPKFromLMKToZMK(String zmk, String zpk) { ProtoGC proto = new ProtoGC(); @@ -7709,8 +7993,8 @@ public class SydApi4j implements SydApi { /** * 2.1生成并打印一个ZMK成份 * 生成一个随机的ZMK成份,在连接到HSM的打印机上打印并将加密值返回给主机 - * @return - * lmkKey: zmk 头 + LMK对04-05变种下加密的ZMK成份 + * + * @return lmkKey: zmk 头 + LMK对04-05变种下加密的ZMK成份 */ public RetWrap genZMKAndPrint() { ProtoOC proto = new ProtoOC(); @@ -7768,11 +8052,11 @@ public class SydApi4j implements SydApi { /** * 1.4 由2-9个密钥成份组成一个密钥(=) -> : code = 23 ( 0x17 ) msg = 未定义的错误 + * * @param keyType 密钥类型 - * @param keys 所有成分 - * @return - * lmkKey: lmk 头 + LMK 加密下的密钥。 - * keyCheck: + * @param keys 所有成分 + * @return lmkKey: lmk 头 + LMK 加密下的密钥。 + * keyCheck: */ public RetWrap composeKey(String keyType, String[] keys) { @@ -7836,12 +8120,13 @@ public class SydApi4j implements SydApi { } + /** * 17.9 角色认证(+) -> -> : code = 2 ( 0x2 ) msg = 签名验证错误 + * * @param roleInfo 角色信息,IC 卡内存放的角色信息密文(LMK14-15) - * @return - * roleType: 角色类型,1:系统管理员,2:密钥管理员,3: 配置管理员 - * roleId: 角色ID, 1:管理员1,2:管理员2 + * @return roleType: 角色类型,1:系统管理员,2:密钥管理员,3: 配置管理员 + * roleId: 角色ID, 1:管理员1,2:管理员2 */ public RetWrap roleVerify(String roleInfo) { Proto61 proto = new Proto61(); @@ -7931,12 +8216,12 @@ public class SydApi4j implements SydApi { /** * 17.11 获取应用密钥明文(+) -> PASS - * @param key 密钥(LMK) + * + * @param key 密钥(LMK) * @param checkAlg 校验值算法,0:3DES,1:SM4 - * @return - * keyCheck: 密钥明文的校验值 - * key1: 密钥明文分量1 - * key2: 密钥明文分量2 + * @return keyCheck: 密钥明文的校验值 + * key1: 密钥明文分量1 + * key2: 密钥明文分量2 */ public RetWrap getPlainText(String key, int checkAlg) { @@ -8006,6 +8291,251 @@ public class SydApi4j implements SydApi { return bytes; } - ; + @Override + public String SYMEncrytByKeyIndex(String index, String intPutData) { + RetWrap retWrap = this.SYMEnDeData(true, 1, this.readKey(index), 1, 1, intPutData.getBytes(), null, 0); + String msg_all_en = Util.bytes2HexString((byte[]) retWrap.get("msg_all")); + return msg_all_en; + } + + + @Override + public String SYMDecrytByKeyIndex(String index, String intPutData) { + RetWrap retWrap = this.SYMEnDeData(false, 1, this.readKey(index), 1, 1, Util.hexString2Bytes(intPutData), null, 0); + String msg_all_de = new String(Util.hexString2Bytes(Util.bytes2HexString((byte[]) retWrap.get("msg_all")))); + return msg_all_de; + } + + + @Override + public boolean setDevCert(String equipType, String equipNo, byte[] equipSk, byte[] equipPk, byte[] manuPk, byte[] authSign) { + Proto90 proto = new Proto90(); + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + data.put("equipType", equipType); + data.put("equipNo", equipNo); + data.put("equipSk", equipSk); + data.put("equipPk", equipPk); + data.put("manuPk", manuPk); + data.put("authSign", authSign); + + ByteBuffer bb = proto.rend(packet); + + synchronized (this) { + bb = syncRead(syncSend(bb)); + } + + Packet p = proto.parse(bb); + Map ret = p.toMap(); + if (!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())) { + throw new SydApiException("包序号不匹配", -4); + } else { + ret = (Map) ret.get("data"); + PacketSection error = (PacketSection) ret.get("error"); + if ("00".equals(error.getString())) { + return true; + } else { + throw new SydApiException(error.getInfo(), error.autoInt()); + } + } + } + + + @Override + public boolean changeDevCert(byte[] equipSk, byte[] equipPk, byte[] authSign) { + Proto91 proto = new Proto91(); + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + data.put("equipSk", equipSk); + data.put("equipPk", equipPk); + data.put("authSign", authSign); + + ByteBuffer bb = proto.rend(packet); + + synchronized (this) { + bb = syncRead(syncSend(bb)); + } + + Packet p = proto.parse(bb); + Map ret = p.toMap(); + if (!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())) { + throw new SydApiException("包序号不匹配", -4); + } else { + ret = (Map) ret.get("data"); + PacketSection error = (PacketSection) ret.get("error"); + if ("00".equals(error.getString())) { + return true; + } else { + throw new SydApiException(error.getInfo(), error.autoInt()); + } + } + } + + + /** + * 查询设备证书信息 + * @return + * equipType: 设备型号 + * equipNo: 设备序号 + * equipPk: 设备密钥公钥 + * authSign: 授权签名 + */ + @Override + public RetWrap getDeviceCertiInfo() { + Proto92 proto = new Proto92(); + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + + // 渲染发送 + ByteBuffer bb = proto.rend(packet); + + synchronized (this) { + // 响应解析 + bb = syncRead(syncSend(bb)); + } + + Packet p = proto.parse(bb); + Map ret = p.toMap(); + + if ( + !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes()) + ) { + throw new SydApiException("包序号不匹配", -4); + } + ret = (Map) ret.get("data"); + PacketSection error = (PacketSection) ret.get("error"); + RetWrap retWrap = new RetWrap(); + if ("00".equals(error.getString())) { + PacketSection equipType = (PacketSection) ret.get("equipType"); + PacketSection equipNo = (PacketSection) ret.get("equipNo"); + PacketSection equipPk = (PacketSection) ret.get("equipPk"); + PacketSection authSign = (PacketSection) ret.get("authSign"); + + retWrap.put("equipType", equipType.getString());//设备型号 + retWrap.put("equipNo", equipNo.getString()); //设备序号 + retWrap.put("equipPk", equipPk.getBytes()); //设备密钥公钥 + retWrap.put("authSign", authSign.getBytes()); //授权签名 + return retWrap; + } else { + return retWrap; + } + } + + + @Override + public String deviceSignC(byte[] orgData) { + Proto97 proto = new Proto97(); + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + data.put("hashData", orgData); + + ByteBuffer bb = proto.rend(packet); + synchronized (this) { + bb = syncRead(syncSend(bb)); + } + + SectionValue sv = new SectionValue(); + sv.setValue(new byte[]{bb.get(12), bb.get(13)}); + PacketSection error = new PacketSection(sv); + if (0 != error.autoInt()) { + throw new SydApiException(error.getInfo(), error.autoInt()); + } else { + bb.position(14); + byte[] v = new byte[4]; + bb.get(v, 0, v.length); + int a = Util.a2i(v, 10); + byte[] s = new byte[a]; + bb.get(s, 0, a); + return Util.encodeBase64(s); + } + } + + + @Override + public boolean setToken(byte[] token) { + Proto98 proto = new Proto98(); + + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + data.put("token", token); + + ByteBuffer bb = proto.rend(packet); + + synchronized (this) { + bb = syncRead(syncSend(bb)); + } + + Packet p = proto.parse(bb); + Map ret = p.toMap(); + if (!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())) { + throw new SydApiException("包序号不匹配", -4); + } else { + ret = (Map) ret.get("data"); + PacketSection error = (PacketSection) ret.get("error"); + if ("00".equals(error.getString())) { + return true; + } else { + throw new SydApiException(error.getInfo(), error.autoInt()); + } + } + } + + + @Override + public byte[] calcAuthHead(byte[] certiContent) { + Proto99 proto = new Proto99(); + HashMap packet = new HashMap(); + HashMap data = new HashMap(); + packet.put("data", data); + PacketSN sn = PacketSN.gen(); + packet.put("header", sn.getSn().array()); + data.put("certiContent", certiContent); + + // 渲染发送 + ByteBuffer bb = proto.rend(packet); + + synchronized (this) { + // 响应解析 + bb = syncRead(syncSend(bb)); + } + + Packet p = proto.parse(bb); + Map ret = p.toMap(); + + if ( + !Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes()) + ) { + throw new SydApiException("包序号不匹配", -4); + } + ret = (Map) ret.get("data"); +// PacketSection equipType = (PacketSection) ret.get( "equipType" ); +// PacketSection equipNo = (PacketSection) ret.get( "equipNo" ); +// RetWrap retWrap = new RetWrap(); + PacketSection error = (PacketSection) ret.get("error"); + if (!"00".equals(error.getString())) { + throw new SydApiException(error.getInfo(), error.autoInt()); + } else { + PacketSection authenCode = (PacketSection) ret.get("authenCode"); + return authenCode.getBytes(); + } +// retWrap.put( "equipType", equipType.getString() );//设备型号 +// retWrap.put( "equipNo", equipNo.getString() ); //设备序号 +// retWrap.put( "authenCode", authenCode.getBytes() ); //认证码 + } } diff --git a/src/main/java/racal/sunyard/main/SydApiBuilder.java b/src/main/java/racal/sunyard/main/SydApiBuilder.java index 505c2a8..4af3e1e 100644 --- a/src/main/java/racal/sunyard/main/SydApiBuilder.java +++ b/src/main/java/racal/sunyard/main/SydApiBuilder.java @@ -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 { diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java new file mode 100644 index 0000000..6dbf50d --- /dev/null +++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java @@ -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); + } +}