diff --git a/DProto/4D41.xml b/DProto/4D41.xml
index 420cbee..6c9b20f 100644
--- a/DProto/4D41.xml
+++ b/DProto/4D41.xml
@@ -34,11 +34,9 @@
- 0
- 1
diff --git a/DProto/4D43.xml b/DProto/4D43.xml
index 79fdf86..9ec141f 100644
--- a/DProto/4D43.xml
+++ b/DProto/4D43.xml
@@ -34,11 +34,9 @@
- 0
- 1
diff --git a/DProto/8008.xml b/DProto/8008.xml
new file mode 100644
index 0000000..4cbd3c0
--- /dev/null
+++ b/DProto/8008.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+ 8008
+
+
+
+
+
+
+
+
+
+
+
+
+ 若没有特别查询条件,则值为“ 1 = 1 ”
+
+
+
+
+
+
+
+ 8009
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0:起始包
+ 1:中间包
+ 2:结束包
+ (可能hi因为字节对此,后三字节为垃圾值)
+
+
+
+ 主机字节序
+
+
+
+ 主机字节序
+
+
+
+ 0:固定长度包
+ 1:变长包,用@分隔
+ 目前默认为0,
+
+
+
+ 目前固定128,若不够用,可用考虑改为256
+
+
+
+ 证书DN
+
+
+
+
+
+
+
+
+
diff --git a/DProto/8009.xml b/DProto/8009.xml
new file mode 100644
index 0000000..cce0845
--- /dev/null
+++ b/DProto/8009.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+ 8009
+
+
+
+
+
+
+
+
+
+
+ 机构号长度
+
+
+
+ 机构号,可选
+
+
+
+
+
+
+
+ 800A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/sunyard/RetWrap.java b/src/main/java/com/sunyard/RetWrap.java
index 17cbb2a..f94fb75 100644
--- a/src/main/java/com/sunyard/RetWrap.java
+++ b/src/main/java/com/sunyard/RetWrap.java
@@ -8,4 +8,202 @@ import java.util.HashMap;
*/
public class RetWrap extends HashMap{
+ public static String transMsg(int retCode){
+ String msg;
+ switch (retCode){
+ case -1:
+ case -2:
+ case -3:
+ msg = "网络错误";
+ break;
+ case -4:
+ msg = "返回包的序列号有误";
+ break;
+ case -5:
+ msg = "返回包的命令码有误";
+ break;
+ case -6:
+ msg = "输出缓冲区预留太小";
+ break;
+ case -25:
+ msg = "输入的 HASH 值长度应该为 32 个字节";
+ break;
+ case -26:
+ msg = "用户标识超长(应该<=16) ";
+ break;
+ case -27:
+ msg = "数据类型不合法 ";
+ break;
+ case 33:
+ msg = "检索的数据或密钥不存在 ";
+ break;
+ case 4:
+ msg = "DER 编码格式错误(公钥) ";
+ break;
+ case 21:
+ msg = "输入的数据格式错误 ";
+ break;
+ case 19:
+ msg = "数据解密错(C3) ";
+ break;
+ case 2:
+ msg = "签名验证错误 ";
+ break;
+ case 32770:
+ msg = "签名验证错误(P7) ";
+ break;
+ case 36868:
+ msg = "DN 所指向的实体不存在 ";
+ break;
+ case 32884:
+ msg = "证书或签名数据的格式错 ";
+ break;
+ case 36865:
+ msg = "不支持的命令";
+ break;
+ case 36866:
+ msg = "数据库操作错误";
+ break;
+ case 36867:
+ msg = "数据记录已经存在";
+ break;
+ case 36869:
+ msg = "加密卡错误";
+ break;
+ case 36870:
+ msg = "系统错误(加密数据)";
+ break;
+ case 36871:
+ msg = "CRL文件中包含的废除证书太多(系统限制200个)";
+ break;
+ case 36872:
+ msg = "用户证书不在此废除的证书之列";
+ break;
+ case 36874:
+ msg = "IC卡错误";
+ break;
+ case 36875:
+ msg = "IC卡口令验证错误,请重新连接";
+ break;
+ case 36876:
+ msg = "IC卡编号错误,请重新连接";
+ break;
+ case 36877:
+ msg = "IC卡角色错误,请重新连接";
+ break;
+ case 36878:
+ msg = "IC卡初始化错误,请重新插入";
+ break;
+ case 36879:
+ msg = "IC卡已初始化";
+ break;
+ case 36880:
+ msg = "不是空白卡";
+ break;
+ case 36881:
+ msg = "IC卡未初始化";
+ break;
+ case 32769:
+ msg = "签名出错,请核对索引号";
+ break;
+ case 32772:
+ msg = "证书过期";
+ break;
+ case 32773:
+ msg = "该证书发行者不可信";
+ break;
+ case 32774:
+ msg = "证书格式错";
+ break;
+ case 32775:
+ msg = "机构ID不合法";
+ break;
+ case 32776:
+ msg = "此证书属于根证书,不在用户证书管理范围";
+ break;
+ case 32777:
+ msg = "产生证书请求出错";
+ break;
+ case 32784:
+ msg = "该证书已被废弃";
+ break;
+ case 28673:
+ msg = "随机数的时效已过";
+ break;
+ case 28674:
+ msg = "登录超时";
+ break;
+ case 28675:
+ msg = "登录口令错";
+ break;
+ case 28677:
+ msg = "操作功能非法使用";
+ break;
+ case 28678:
+ msg = "系统已签退,请重新登录";
+ break;
+ case 28679:
+ msg = "操作权限限制";
+ break;
+ case 28680:
+ msg = "随机数据长度超过系统的要求";
+ break;
+ case 28681:
+ msg = "此操作员不存在";
+ break;
+ case 28688:
+ msg = "此操作员已经存在";
+ break;
+ case 28689:
+ msg = "该IP是本地IP,不能进行分发";
+ break;
+ case 24581:
+ msg = "文件在设备后端读写失败";
+ break;
+ case 24582:
+ msg = "ERROR_HANDLE_NULL";
+ break;
+ case 24585:
+ msg = "升级文件格式有误,请核对后再操作";
+ break;
+ case 24592:
+ msg = "命令执行过程中出现系统错误";
+ break;
+ case 24593:
+ msg = "本功能升级已经结束,不用重复操作";
+ break;
+ case 24594:
+ msg = "数据不合法或格式不正确";
+ break;
+ case 24595:
+ msg = "中心标识未设,请先设置中心标识";
+ break;
+ case 24596:
+ msg = "加密密钥不存在";
+ break;
+ case 24597:
+ msg = "密钥应用超过10个(密钥必须索引0-9)";
+ break;
+ case 24598:
+ msg = "行标识没有设置";
+ break;
+ case 24577:
+ msg = "查询类型错误";
+ break;
+ case 24578:
+ msg = "查询格式错误";
+ break;
+ case 24579:
+ msg = "数据不合法";
+ break;
+ case 24580:
+ msg = "系统的口令错误";
+ break;
+ default:
+ msg = "未定义的错误";
+ }
+
+ return msg;
+ }
+
}
diff --git a/src/main/java/com/sunyard/SydApi.java b/src/main/java/com/sunyard/SydApi.java
index 8070a70..8311bb3 100644
--- a/src/main/java/com/sunyard/SydApi.java
+++ b/src/main/java/com/sunyard/SydApi.java
@@ -20,6 +20,14 @@ public interface SydApi extends SydRawApi, SydCertApi, SydCryptionApi, SydGenApi
int NALG_SM4 = 0x01;
int NALG_AES = 0x02;
+ //清算总行密押MAC填充模式
+ byte MIYA_FULL_WEAK = 0x30;
+ byte MIYA_FULL_FORCE = 0x31;
+ //清算总行密押MAC长度标识
+ byte MIYA_MAC_LEN_4 = 0x31;
+ byte MIYA_MAC_LEN_8 = 0x32;
+ byte MIYA_MAC_LEN_16 = 0x33;
+
String RET_CIPHER_KEY = "CipherKey";
String RET_SESSION_KEY = "SessionKey";
String RET_PUBLIC_KEY = "PublicKey";
diff --git a/src/main/java/com/sunyard/inf/SydCertApi.java b/src/main/java/com/sunyard/inf/SydCertApi.java
index 0816dbb..34a53f5 100644
--- a/src/main/java/com/sunyard/inf/SydCertApi.java
+++ b/src/main/java/com/sunyard/inf/SydCertApi.java
@@ -1,8 +1,11 @@
package com.sunyard.inf;
+import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
+import java.io.UnsupportedEncodingException;
+
/**
* 证书操作相关接口
*/
@@ -29,6 +32,11 @@ public interface SydCertApi {
byte[] dn
);
+ String RSAGetPublicKeyC(
+ String userId,
+ int nKeyTypes
+ );
+
/**
* 通过使用者 ID 获得使用者的 SM2 公钥(DER 编码)。
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
@@ -79,4 +87,19 @@ public interface SydCertApi {
String sign
);
+ /**
+ * 查询所有证书
+ * @param dataFlag 数据包标志 0:起始包 1:中间包 2:结束包
+ * @return
+ */
+ RetWrap getAllCert(int dataFlag) throws UnsupportedEncodingException;
+
+ /**
+ * 上传指定证书到加密设备
+ * @param certData 证书的字节数组
+ * @param organizationId 机构号的字节数组
+ * @return
+ */
+ RetWrap importCert(byte[] certData, byte[] organizationId);
+
}
diff --git a/src/main/java/com/sunyard/inf/SydCryptionApi.java b/src/main/java/com/sunyard/inf/SydCryptionApi.java
index 586e152..409e86f 100644
--- a/src/main/java/com/sunyard/inf/SydCryptionApi.java
+++ b/src/main/java/com/sunyard/inf/SydCryptionApi.java
@@ -1,5 +1,6 @@
package com.sunyard.inf;
+import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sunyard.RetWrap;
/**
@@ -94,6 +95,77 @@ interface SydASYMApi {
String userId,
String pEnData
);
+
+ /**
+ * 使用外部私钥解密
+ * @param sk
+ * @param enData
+ * @return
+ */
+ byte[] SM2Decrypt(byte[] sk, String enData);
+
+ /**
+ * 用指定的 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 Base64DecodingException;
+
+
+ /**
+ * 使用外部私钥解密
+ * @param sk
+ * @param enData
+ * @return
+ */
+ public byte[] RSADecrypt(String sk, String enData) throws Base64DecodingException;
+
+
+ /**
+ * 非对称公钥加密
+ * @param alg
+ * @param pk
+ * @param data
+ * @return
+ */
+ public byte[] encryptByPk(int alg, String pk, byte[] data);
+
+
+ /**
+ * 非对称私钥解密
+ * @param alg
+ * @param sk 私钥值
+ * @param data
+ * @return
+ */
+ public byte[] decryptBySk(int alg, String sk, byte[] data);
+
+
+ /**
+ * 非对称私钥解密
+ * @param alg
+ * @param user
+ * @param data
+ * @return
+ */
+ public byte[] decryptBySkC(int alg, String user, byte[] data);
}
diff --git a/src/main/java/com/sunyard/inf/SydPledge.java b/src/main/java/com/sunyard/inf/SydPledge.java
index d6e70ef..44b637a 100644
--- a/src/main/java/com/sunyard/inf/SydPledge.java
+++ b/src/main/java/com/sunyard/inf/SydPledge.java
@@ -10,7 +10,19 @@ public interface SydPledge {
* @param Data 原始数据
* @return MAC 长度为 8 的 HEX字符串
*/
- public String GenerateMIYA(String AreaCode, int Version, int Alg, byte[] Data);
+ String GenerateMIYA(String AreaCode, int Version, int Alg, byte[] Data);
+
+ /**
+ *
+ * @param AreaCode 地区代码 6 位
+ * @param Version 版本号
+ * @param Alg SydApi.NALG_3DES/SydApi.NALG_SM4
+ * @param Data 原始数据
+ * @param fullFlag 填充类型
+ * @param macLenFlag MAC 长度标识
+ * @return
+ */
+ String GenerateMIYA(String AreaCode, int Version, int Alg, byte[] Data, byte fullFlag, byte macLenFlag);
/**
*
@@ -21,6 +33,19 @@ public interface SydPledge {
* @param Data 原始数据
* @return true=核押通过 false=核押不通过
*/
- public boolean VerifyMIYA(String AreaCode, int Version, int Alg, String MAC, byte[] Data);
+ boolean VerifyMIYA(String AreaCode, int Version, int Alg, String MAC, byte[] Data);
+
+ /**
+ *
+ * @param AreaCode 地区代码 6 位
+ * @param Version 版本号
+ * @param Alg SydApi.NALG_3DES/SydApi.NALG_SM4
+ * @param mac 长度为 8 的 HEX字符串
+ * @param Data 原始数据
+ * @param fullFlag 填充类型
+ * @param macLenFlag MAC 长度标识
+ * @return
+ */
+ boolean VerifyMIYA(String AreaCode, int Version, int Alg, String mac, byte[] Data, byte fullFlag, byte macLenFlag);
}
diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java
index 760a6b4..1817c17 100644
--- a/src/main/java/racal/sunyard/main/SydApi4j.java
+++ b/src/main/java/racal/sunyard/main/SydApi4j.java
@@ -535,6 +535,7 @@ public class SydApi4j implements SydApi {
}
+ @Override
public RetWrap genComposeKey(String keyType, char keySolution, String keyClearPattern) {
ProtoAA proto = new ProtoAA();
@@ -825,6 +826,127 @@ public class SydApi4j implements SydApi {
return GetX509CertInfo(new String(pCertInfo));
}
+ @Override
+ public RetWrap getAllCert(int dataFlag) throws UnsupportedEncodingException {
+ Proto8008 proto = new Proto8008();
+
+ // 填充数据
+ HashMap packet = new HashMap();
+
+ HashMap data = new HashMap();
+ packet.put("data", data);
+
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("dataFlag$option", dataFlag);
+
+ String sqlite3 = "1 = 1 ";
+ data.put("sqlite3", sqlite3);
+
+ // 渲染发送
+ 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]))) {
+
+ throw new SydApiException(error.getInfo(), error.autoInt());
+ }
+
+ RetWrap r = new RetWrap();
+
+ PacketSection resDataFlag = (PacketSection) ret.get("dataFlag");
+ r.put("dataFlag", (int) resDataFlag.getBytes()[0]);
+ PacketSection certAllNum = (PacketSection) ret.get("certAllNum");
+ r.put("certAllNum", (int) certAllNum.getBytes()[0]);
+ PacketSection realCertNum = (PacketSection) ret.get("realCertNum");
+ r.put("realCertNum", (int) realCertNum.getBytes()[0]);
+ PacketSection dataAttrFlag = (PacketSection) ret.get("dataAttrFlag");
+ r.put("dataAttrFlag", (int) dataAttrFlag.getBytes()[0]);
+ 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") );
+ }
+
+ r.put("certDNs", certs.toArray(new String[0]));
+
+ return r;
+ }
+
+ @Override
+ public RetWrap importCert(byte[] certData, byte[] organizationId) {
+
+ Proto8009 proto = new Proto8009();
+
+ // 填充数据
+ HashMap packet = new HashMap();
+
+ HashMap data = new HashMap();
+ packet.put("data", data);
+
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("certData", certData );
+
+ if(null != organizationId && organizationId.length > 0){
+ data.put("organizationId", organizationId );
+ }
+
+// int length = certData.length;
+// System.out.println("dataLength: " + length);
+
+ // 渲染发送
+ ByteBuffer bb = proto.rend(packet);
+
+// String s = Util.bytes2HexString(Util.toArray(bb));
+// System.out.println(s);
+ 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();
+
+// String s1 = Util.bytes2HexString(be);
+// System.out.println(s1);
+ RetWrap r = new RetWrap();
+ r.put("retCode", true);
+
+ 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());
+ }
+ return r;
+ }
public SydApi4j() {
// if (null == pset) {
@@ -1146,7 +1268,7 @@ public class SydApi4j implements SydApi {
}
- private byte[] repackEncrypt(HashMap packet) {
+ private byte[] repackEncrypt(HashMap packet) {
HashMap data = (HashMap) packet.get("data");
int v = ((byte[]) data.get("msg")).length;
@@ -1155,7 +1277,7 @@ public class SydApi4j implements SydApi {
repack("E0", 2048, packet, new PackCallBack() {
@Override
- public void circle(int packSn, HashMap packet, Map ret) {
+ public void circle(int packSn, HashMap packet, Map ret) {
bbs.put(((PacketSection) ret.get("msg")).getBytes());
}
@@ -1164,20 +1286,20 @@ public class SydApi4j implements SydApi {
return Util.toArray(bbs);
}
- private RetWrap repackEncrypt(HashMap packet,Boolean isDe) {
+ private RetWrap repackEncrypt(HashMap packet, Boolean isDe) {
HashMap data = (HashMap) packet.get("data");
int v = ((byte[]) data.get("msg")).length;
final ByteBuffer bbs = ByteBuffer.allocate(v + 1024);
- int packSize=2048;
- int packSizeDe=packSize+16;
+ int packSize = 2048;
+ int packSizeDe = packSize + 16;
// int fm = (int) data.get("fullMode$option");
int fm = (Integer) data.get("fullMode$option");
- if (isDe && 1 == fm && v<=packSizeDe && v>packSize) {
+ if (isDe && 1 == fm && v <= packSizeDe && v > packSize) {
//说明传入数据正好是2048,pkcs模式下机密来的,解密时需当做唯一包处理
- packSize=packSizeDe;
+ packSize = packSizeDe;
}
RetWrap retWrap = repack("E0", packSize, packet, new PackCallBack() {
@Override
@@ -1230,9 +1352,9 @@ public class SydApi4j implements SydApi {
//>2k,即进行分块,首尾包进行解密-> 报错
//如果是PKCS模式,packSize应为2064,才能当做唯一包进行解密
- int fm= (Integer) data.get("fullMode$option");
- int loop=0;
- int tailLen=0;
+ int fm = (Integer) data.get("fullMode$option");
+ int loop = 0;
+ int tailLen = 0;
//解密时,PKCS,2048 data = new HashMap();
// 确认算法
- if ( isEn ){
+ if (isEn) {
switch (nAlg) {
case 0:
data.put("alg$option", 0x0);
@@ -1684,20 +1804,19 @@ public class SydApi4j implements SydApi {
data.put("msg", pInData);
packet.put("data", data);
- // Map map=new HashMap<>();
+ // Map map=new HashMap<>();
- // Map map = repackEncrypt(packet);
+ // Map map = repackEncrypt(packet);
- // Map map = repackEncrypt(packet,!isEn);
+ // Map map = repackEncrypt(packet,!isEn);
RetWrap retWrap = repackEncrypt(packet, !isEn);
- // System.out.println(retWrap);
+ // System.out.println(retWrap);
return retWrap;
}
-
@Override
public byte[] SYMEncryptData(int nAlg, String seesionKey, int fullMode, byte[] pInData) {
@@ -1737,6 +1856,7 @@ public class SydApi4j implements SydApi {
}
+ @Override
public byte[] SYMEncryptData_nofill(int nAlg, String seesionKey, byte[] pInData) {
if (2 == nAlg && 'L' != seesionKey.charAt(0)) {
@@ -2206,7 +2326,7 @@ public class SydApi4j implements SydApi {
@Override
public RetWrap SM2OrRSAGenKeyPair(int keyType, String index, int length) {
- System.out.println( getClass().getClassLoader().hashCode() );
+ System.out.println(getClass().getClassLoader().hashCode());
ProtoE2 proto = new ProtoE2();
HashMap packet = new HashMap();
@@ -2256,7 +2376,8 @@ public class SydApi4j implements SydApi {
}
- public boolean RSAVerify(int HashMark, int nOrgDataType, byte[] publickey, byte[] orgData, byte[] base64Sign) {
+ @Override
+ public boolean RSAVerify(int HashMark, int nOrgDataType, byte[] publicKey, byte[] orgData, byte[] base64Sign) {
Proto7C proto = new Proto7C();
byte[] sign = base64Sign;
@@ -2269,7 +2390,7 @@ public class SydApi4j implements SydApi {
data.put("hashMark$option", HashMark);
data.put("signature", sign);
data.put("hashData", orgData);
- data.put("publicKey", publickey);
+ data.put("publicKey", publicKey);
ByteBuffer bb = proto.rend(packet);
@@ -2294,6 +2415,7 @@ public class SydApi4j implements SydApi {
}
}
+ @Override
public byte[] RSASignC(String privateKeyIndex, int HashMark, int nOrgDataType, byte[] orgData) {
Proto7B proto = new Proto7B();
HashMap packet = new HashMap();
@@ -2308,7 +2430,6 @@ public class SydApi4j implements SydApi {
data.put("privateKeyTag", SYMUtil.genPrivateKeyMark(privateKeyIndex, "000", "00000001"));
-
ByteBuffer bb = proto.rend(packet);
synchronized (this) {
@@ -2370,7 +2491,7 @@ public class SydApi4j implements SydApi {
RetWrap rw = new RetWrap();
byte[] lmks = ((PacketSection) ret.get("lmk")).getBytes();
byte[] lmkHeads = ((PacketSection) ret.get("lmkHead")).getBytes();
- byte[] bs= new byte[lmks.length + lmkHeads.length];
+ byte[] bs = new byte[lmks.length + lmkHeads.length];
System.arraycopy(lmkHeads, 0, bs, 0, lmkHeads.length);
System.arraycopy(lmks, 0, bs, lmkHeads.length, lmks.length);
rw.put("lmkKey", bs);
@@ -2380,6 +2501,46 @@ public class SydApi4j implements SydApi {
}
}
+ @Override
+ public String RSAGetPublicKeyC(String userId, int nKeyType) {
+
+ //ProtocolRender render = pset.getProtocolReqRender("QQ");
+ ProtoQQ proto = new ProtoQQ();
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ packet.put("data", data);
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("privateKeyTag", SYMUtil.genPrivateKeyMark(userId, 0 == nKeyType ? "000" : "001", "00000001"));
+ // 渲染发送
+ ByteBuffer bb = proto.rend(packet);
+ //System.out.println(Util.bytes2HexString(Util.toArray(bb)));
+ 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());
+ }
+ int len = Integer.parseInt(((PacketSection) ret.get("publicLen")).getString());
+ if (len == 128) {
+ return "03420004" + ((PacketSection) ret.get("publicKey")).getString();
+ }
+
+ System.out.println("len=" + len);
+ return Util.bytes2HexString(((PacketSection) ret.get("publicKey")).getBytes());
+ }
+
@Override
public String SM2GetPublicKeyC(String userId, int nKeyType) {
@@ -2688,13 +2849,12 @@ public class SydApi4j implements SydApi {
}
-
public boolean SM2Verify(
int nOrgDataType,
byte[] publicKey,
byte[] orgData,
String base64Sign
- ){
+ ) {
String certNo = "1234567812345678";
//ProtocolRender render = pset.getProtocolReqRender("75");
Proto75 proto = new Proto75();
@@ -2732,7 +2892,6 @@ public class SydApi4j implements SydApi {
}
-
@Override
public String SM2Sign(
int nOrgDataType,
@@ -2781,8 +2940,6 @@ public class SydApi4j implements SydApi {
}
-
-
@Override
public boolean SM2VerifyCustomized(String certNo, byte[] orgData, String base64Sign) {
@@ -2950,6 +3107,7 @@ public class SydApi4j implements SydApi {
* @param pk HEX 格式的公钥
* @return
*/
+ @Override
public byte[] encryptByPk(int alg, String pk, byte[] data) {
byte[] algBin = 0 == alg ? DTO77.Req.Data.AlgorithmKeyOptions.OPVRSA.getBin() : DTO77.Req.Data.AlgorithmKeyOptions.OPVSM2.getBin();
@@ -2990,6 +3148,38 @@ public class SydApi4j implements SydApi {
return decryptBySk(alg, sk, SYMUtil.base64EnData2DerEnData(data));
}
+ @Override
+ public byte[] decryptBySkC(int alg, String userId, byte[] data) {
+ byte[] algBin = 0 == alg ? DTO78.Req.Data.AlgorithmKeyOptions.OPVRSA.getBin() : DTO78.Req.Data.AlgorithmKeyOptions.OPVSM2.getBin();
+
+ Proto78 proto = new Proto78();
+ DTO78.Req req = new DTO78.Req()
+ .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 )
+ .closeBuilding();
+
+ ByteBuffer bb = proto.rend( req.toSoup() );
+ synchronized (this) {
+ // 响应解析
+ bb = syncRead(syncSend(bb));
+ }
+
+ Packet p = proto.parse(bb);
+ DTO78.Res res = new DTO78.Res();
+ res = res.fullFromSoup( proto.parse(bb).resSoup() );
+
+ if ( "3030".equals(res.getData().getErrorAsHex()) ){
+ return res.getData().getDataAsBin();
+ } else {
+ throw SydApiException.fromBin(res.getData().getErrorAsBin(), res.getData().getErrorCn());
+ }
+ }
+
+ @Override
public byte[] decryptBySk(int alg, String sk, byte[] data) {
byte[] algBin = 0 == alg ? DTO78.Req.Data.AlgorithmKeyOptions.OPVRSA.getBin() : DTO78.Req.Data.AlgorithmKeyOptions.OPVSM2.getBin();
@@ -3023,6 +3213,56 @@ public class SydApi4j implements SydApi {
}
}
+
+ /**
+ * 用指定的 RSA 私钥对指定的密文数据进行加密。
+ *
+ * @param publicKey 私钥串,DER 编码,HEX 格式。
+ * @param pOrgData 加密的数据。
+ * @return 加密的数据 base64 编码。
+ */
+ @Override
+ public String RSAEncrypt(
+ String publicKey,
+ byte[] pOrgData
+ ) {
+ return Util.encodeBase64(encryptByPk(0, publicKey, pOrgData));
+ }
+
+
+ /**
+ * 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
+ *
+ * @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
+ * @param pEnData 加密的数据,base64 编码。
+ * @return 明文数据。
+ */
+ @Override
+ public byte[] RSADecryptC(
+ String userId,
+ String pEnData
+ ) {
+
+ return decryptBySk(0, userId, Util.decodeBase64(pEnData));
+
+ }
+
+
+ /**
+ * 使用外部私钥解密
+ *
+ * @param sk HEX 私钥值
+ * @param enData base64 值
+ * @return
+ */
+ @Override
+ public byte[] RSADecrypt(String sk, String enData) {
+
+ return decryptBySk(0, sk, Util.decodeBase64(enData));
+
+ }
+
+
@Override
public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) {
Proto77 proto = new Proto77();
@@ -3059,6 +3299,48 @@ public class SydApi4j implements SydApi {
return SYMUtil.derEnData2Base64EnData(((PacketSection) ret.get("cipherData")).getBytes());
}
+
+ @Override
+ public byte[] SM2Decrypt(byte[] sk, String enData) {
+ //ProtocolRender render = pset.getProtocolReqRender("78");
+ Proto78 proto = new Proto78();
+
+ byte[] pOrgData = SYMUtil.base64EnData2DerEnData(enData);
+
+ // 填充数据
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ packet.put("data", data);
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ data.put("AlgorithmKey$option", 1);
+ data.put("infoData", pOrgData);
+ data.put("privateKeyTag", "999999999999999999999999999");
+ data.put("privateKey", sk);
+ // 渲染发送
+ 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());
+ }
+
+ return ((PacketSection) ret.get("data")).getBytes();
+ }
+
+
@Override
public byte[] SM2DecryptC(String userId, String enData) {
//ProtocolRender render = pset.getProtocolReqRender("78");
@@ -3380,8 +3662,8 @@ public class SydApi4j implements SydApi {
}
RetWrap rw = new RetWrap();
- System.out.println("lmkHead" + ((PacketSection) ret.get("lmkHead")).getString() +
- "\nlmk" + ((PacketSection) ret.get("lmk")).getString());
+// System.out.println("lmkHead" + ((PacketSection) ret.get("lmkHead")).getString() +
+// "\nlmk" + ((PacketSection) ret.get("lmk")).getString());
rw.put(SydApi.RET_SESSION_KEY, ((PacketSection) ret.get("lmkHead")).getString() +
@@ -4247,6 +4529,12 @@ public class SydApi4j implements SydApi {
@Override
public String GenerateMIYA(String AreaCode, int Version, int Alg, byte[] Data) {
+ return GenerateMIYA(AreaCode, Version, Alg, Data, MIYA_FULL_WEAK, MIYA_MAC_LEN_4);
+ }
+
+
+ @Override
+ public String GenerateMIYA(String AreaCode, int Version, int Alg, byte[] Data, byte fullFlag, byte macLenFlag) {
if (Version < 0 || Version > 999) {
throw new SydApiException("Version 范围不对", 21);
}
@@ -4287,6 +4575,8 @@ public class SydApi4j implements SydApi {
data.put("MACData", Util.bytes2HexString(Data).getBytes());
data.put("key", key);
+ data.put("full", fullFlag);
+ data.put("macLen", macLenFlag);
// 渲染发送
ByteBuffer bb = proto.rend(packet);
@@ -4317,6 +4607,11 @@ public class SydApi4j implements SydApi {
@Override
public boolean VerifyMIYA(String AreaCode, int Version, int Alg, String mac, byte[] Data) {
+ return VerifyMIYA(AreaCode, Version, Alg, mac, Data, MIYA_FULL_WEAK, MIYA_MAC_LEN_4);
+ }
+
+ @Override
+ public boolean VerifyMIYA(String AreaCode, int Version, int Alg, String mac, byte[] Data, byte fullFlag, byte macLenFlag) {
if (Version < 0 || Version > 999) {
throw new SydApiException("Version 范围不对", 21);
@@ -4359,6 +4654,8 @@ public class SydApi4j implements SydApi {
data.put("MAC", mac);
data.put("MACData", Util.bytes2HexString(Data).getBytes());
data.put("key", key);
+ data.put("full", fullFlag);
+ data.put("macLen", macLenFlag);
// 渲染发送
ByteBuffer bb = proto.rend(packet);
@@ -4735,7 +5032,7 @@ public class SydApi4j implements SydApi {
bb = syncRead(syncSend(bb));
}
- Packet p = proto.parse(bb,packet);
+ Packet p = proto.parse(bb, packet);
Map ret = p.toMap();
if (
@@ -5578,7 +5875,7 @@ public class SydApi4j implements SydApi {
RetWrap rw = new RetWrap();
byte[] keys = ((PacketSection) ret.get("key")).getBytes();
byte[] keyHeads = ((PacketSection) ret.get("keyHead")).getBytes();
- byte[] bs= new byte[keys.length + keyHeads.length];
+ 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);
@@ -5645,7 +5942,19 @@ public class SydApi4j implements SydApi {
return true;
}
- //9.2 数据转加密指令(Y0)(=) -> pass (注:密文数据那项不一定需要传加密出来的数据)
+ /**
+ * 数据转加密指令(Y0)(=) -> pass (注:密文数据那项不一定需要传加密出来的数据)
+ * @param srcType 源密钥类型
+ * @param sca 源算法SCA
+ * @param desKeyType 目的秘钥类型
+ * @param dca 目的算法SCA
+ * @param roundModel 加密模式
+ * @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) {
ProtoY0 proto = new ProtoY0();
HashMap packet = new HashMap();
@@ -7047,7 +7356,7 @@ public class SydApi4j implements SydApi {
}
//1.1生成一个对称密钥(*) -> pass (对比之前添加了可产生ZMK加密下的密钥)
- public RetWrap genSymKey(int mode,String keyType, char solution,String zmk) {
+ public RetWrap genSymKey(int mode, String keyType, char solution, String zmk) {
ProtoA0 proto = new ProtoA0();
HashMap packet = new HashMap();
HashMap data = new HashMap();
@@ -7055,7 +7364,7 @@ public class SydApi4j implements SydApi {
packet.put("data", data);
PacketSN sn = PacketSN.gen();
packet.put("header", sn.getSn().array());
- data.put("mode$option",mode);
+ data.put("mode$option", mode);
data.put("keyType", keyType);
data.put("solution", solution);
data.put("zmk", zmk);
@@ -7086,7 +7395,7 @@ public class SydApi4j implements SydApi {
System.arraycopy(lmkHeads, 0, bs1, 0, lmkHeads.length);
System.arraycopy(lmks, 0, bs1, lmkHeads.length, lmks.length);
rw.put("lmkKey", bs1);
- if(1== mode) {
+ if (1 == mode) {
byte[] zmks = ((PacketSection) ret.get("zmk")).getBytes();
byte[] zmkHeads = ((PacketSection) ret.get("zmkHead")).getBytes();
byte[] bs2 = new byte[zmks.length + zmkHeads.length];
@@ -7110,7 +7419,7 @@ public class SydApi4j implements SydApi {
packet.put("data", data);
PacketSN sn = PacketSN.gen();
packet.put("header", sn.getSn().array());
- data.put("roleInfo",roleInfo.getBytes());
+ data.put("roleInfo", roleInfo.getBytes());
ByteBuffer bb = proto.rend(packet);
@@ -7189,7 +7498,7 @@ public class SydApi4j implements SydApi {
}
//17.11 获取应用密钥明文(+) -> PASS
- public RetWrap getPlainText(String key, int checkAlg){
+ public RetWrap getPlainText(String key, int checkAlg) {
ProtoAB proto = new ProtoAB();
// 填充数据
@@ -7213,7 +7522,7 @@ public class SydApi4j implements SydApi {
bb = syncRead(syncSend(bb));
}
//ProtocolParser parser = pset.getProtocolResParse();
- Packet p = proto.parse(bb,packet);
+ Packet p = proto.parse(bb, packet);
Map ret = p.toMap();
if (
!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
@@ -7235,7 +7544,7 @@ public class SydApi4j implements SydApi {
}
@Override
- public byte[] directBytes(byte[] data){
+ public byte[] directBytes(byte[] data) {
//初始化一个和byte长度一样的bb
ByteBuffer bb = ByteBuffer.allocate(data.length);
// 数组放到bb中
@@ -7248,13 +7557,15 @@ public class SydApi4j implements SydApi {
//重置 limit 和postion 值
bb.flip();
//获取bb中有效大小
- int len=bb.limit() - bb.position();
+ int len = bb.limit() - bb.position();
- byte [] bytes=new byte[len];
+ byte[] bytes = new byte[len];
for (int i = 0; i < bytes.length; i++) {
- bytes[i]=bb.get();
+ bytes[i] = bb.get();
}
return bytes;
- };
+ }
+
+ ;
}