From 3636ce7b5d5848c854df9dcc69ce18a0c8ff9e5c Mon Sep 17 00:00:00 2001
From: zhoubin <2023106681@qq.com>
Date: Thu, 10 Mar 2022 16:43:29 +0800
Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=B7=BB=E5=8A=A0SJJ1418=E7=9B=B8?=
=?UTF-8?q?=E5=85=B3=E7=9A=84=E4=B8=80=E4=BA=9B=E7=BB=93=E6=9E=84=E4=BD=93?=
=?UTF-8?q?=E3=80=822=E3=80=81=E6=B7=BB=E5=8A=A0SJJ1418=E6=8C=87=E4=BB=A4?=
=?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E9=83=A8=E5=88=86xml=E6=96=87?=
=?UTF-8?q?=E4=BB=B6=E3=80=823=E3=80=81=E6=B7=BB=E5=8A=A0SJJ1418=E6=8E=A5?=
=?UTF-8?q?=E5=8F=A3=E7=9A=84=E5=AE=9E=E7=8E=B0=E7=B1=BB=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
DProto/SJJ1418/0100.xml | 174 ++++++++
DProto/SJJ1418/0101.xml | 182 +++++++++
DProto/SJJ1418/0102.xml | 183 +++++++++
DProto/SJJ1418/0103.xml | 175 ++++++++
DProto/SJJ1418/0200.xml | 178 ++++++++
src/main/java/com/sunyard/SydApiSDF.java | 48 +++
.../com/sunyard/constant/SDFConstant.java | 39 ++
.../java/com/sunyard/entity/DeviceInfo.java | 228 +++++++++++
.../java/com/sunyard/entity/ECCCipher_st.java | 55 +++
.../com/sunyard/entity/ECCSignnature_st.java | 28 ++
.../sunyard/entity/ECCrefPrivateKey_st.java | 29 ++
.../sunyard/entity/ECCrefPublicKey_st.java | 39 ++
.../com/sunyard/entity/RSArefPriKey_st.java | 73 ++++
.../com/sunyard/entity/RSArefPubKey_st.java | 38 ++
.../entity/SYD_AgreementHandle_st.java | 64 +++
.../com/sunyard/entity/SYD_HashCtx_st.java | 53 +++
.../com/sunyard/entity/SYD_KeyHandle_st.java | 26 ++
.../com/sunyard/entity/SYD_SessionKey_st.java | 26 ++
src/main/java/com/sunyard/util/DataUtil.java | 61 +++
.../java/racal/sunyard/main/SydApiSDF4j.java | 381 ++++++++++++++++++
.../sunyard/sydapi/test/TestAllMethods.java | 10 +
.../sydapi/test/TestAllMethodsSDF.java | 60 +++
22 files changed, 2150 insertions(+)
create mode 100644 DProto/SJJ1418/0100.xml
create mode 100644 DProto/SJJ1418/0101.xml
create mode 100644 DProto/SJJ1418/0102.xml
create mode 100644 DProto/SJJ1418/0103.xml
create mode 100644 DProto/SJJ1418/0200.xml
create mode 100644 src/main/java/com/sunyard/SydApiSDF.java
create mode 100644 src/main/java/com/sunyard/constant/SDFConstant.java
create mode 100644 src/main/java/com/sunyard/entity/DeviceInfo.java
create mode 100644 src/main/java/com/sunyard/entity/ECCCipher_st.java
create mode 100644 src/main/java/com/sunyard/entity/ECCSignnature_st.java
create mode 100644 src/main/java/com/sunyard/entity/ECCrefPrivateKey_st.java
create mode 100644 src/main/java/com/sunyard/entity/ECCrefPublicKey_st.java
create mode 100644 src/main/java/com/sunyard/entity/RSArefPriKey_st.java
create mode 100644 src/main/java/com/sunyard/entity/RSArefPubKey_st.java
create mode 100644 src/main/java/com/sunyard/entity/SYD_AgreementHandle_st.java
create mode 100644 src/main/java/com/sunyard/entity/SYD_HashCtx_st.java
create mode 100644 src/main/java/com/sunyard/entity/SYD_KeyHandle_st.java
create mode 100644 src/main/java/com/sunyard/entity/SYD_SessionKey_st.java
create mode 100644 src/main/java/com/sunyard/util/DataUtil.java
create mode 100644 src/main/java/racal/sunyard/main/SydApiSDF4j.java
create mode 100644 src/test/java/com/sunyard/sydapi/test/TestAllMethodsSDF.java
diff --git a/DProto/SJJ1418/0100.xml b/DProto/SJJ1418/0100.xml
new file mode 100644
index 0000000..888ede6
--- /dev/null
+++ b/DProto/SJJ1418/0100.xml
@@ -0,0 +1,174 @@
+
+
+
+
+
+ 0100
+
+
+
+
+
+
+
+
+ 0100
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 设备信息结构体DEVICEINFO
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DProto/SJJ1418/0101.xml b/DProto/SJJ1418/0101.xml
new file mode 100644
index 0000000..07be424
--- /dev/null
+++ b/DProto/SJJ1418/0101.xml
@@ -0,0 +1,182 @@
+
+
+
+
+
+ 0101
+
+
+
+ 生成随机数的长度
+
+
+
+
+
+
+
+ 0102
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 生成的随机数数据
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DProto/SJJ1418/0102.xml b/DProto/SJJ1418/0102.xml
new file mode 100644
index 0000000..73366ef
--- /dev/null
+++ b/DProto/SJJ1418/0102.xml
@@ -0,0 +1,183 @@
+
+
+
+
+ 0102
+
+
+
+
+
+ 私钥索引密码设备存储私钥的索引值
+
+
+
+ 私钥访问控制码的长度
+
+
+ 使用私钥权限的标识码,固定为8字节
+
+
+
+
+
+
+
+ 0103
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DProto/SJJ1418/0103.xml b/DProto/SJJ1418/0103.xml
new file mode 100644
index 0000000..5099be2
--- /dev/null
+++ b/DProto/SJJ1418/0103.xml
@@ -0,0 +1,175 @@
+
+
+
+
+
+ 0103
+
+
+
+
+ 私钥索引密码设备存储私钥的索引值
+
+
+
+
+
+
+
+ 0104
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DProto/SJJ1418/0200.xml b/DProto/SJJ1418/0200.xml
new file mode 100644
index 0000000..8adef0e
--- /dev/null
+++ b/DProto/SJJ1418/0200.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+ 0200
+
+
+
+
+ 私钥索引密码设备存储私钥的索引值
+
+
+
+
+
+
+
+ 0201
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RSA公钥结构体(RSArefPublicKey)
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/sunyard/SydApiSDF.java b/src/main/java/com/sunyard/SydApiSDF.java
new file mode 100644
index 0000000..a7344a9
--- /dev/null
+++ b/src/main/java/com/sunyard/SydApiSDF.java
@@ -0,0 +1,48 @@
+package com.sunyard;
+
+import com.sunyard.entity.DeviceInfo;
+
+/**
+ * SJJ1418服务器密码机指令集
+ */
+public interface SydApiSDF {
+
+ /**
+ * 建立到指定地址和端口号的加密设备的TCP/IP 连接,返回 TCP/IP 连接句柄。
+ * 如果采用短连接,交易结束,要调用 disconnect() 进行释放连接。
+ * @param ip 加密设备的 IP 地址。
+ * @param port 加密设备的端口号。
+ * @param pwd 保留。
+ * @param timeout 超时时间。
+ * @return 设备操作对象
+ */
+ SydApiSDF connect(String ip, int port, String pwd, int timeout);
+
+ /**
+ * 建立到指定地址和端口号的加密设备的TCP/IP 连接,返回 TCP/IP 连接句柄。
+ * 如果采用短连接,交易结束,要调用 disconnect() 进行释放连接。
+ * @param ip 加密设备的 IP 地址。
+ * @param port 加密设备的端口号。
+ * @param pwd 保留。
+ * @param connectTimeout 链接超时时间。
+ * @param readTimeout 通信超时时间
+ * @return 设备操作对象
+ */
+ SydApiSDF connect(String ip, int port, String pwd, int connectTimeout, int readTimeout);
+
+ /**
+ * 断开连接
+ * @return 0 表示成功;非 0 表示失败;
+ */
+ int disconnect();
+
+
+ /**
+ * 获取设备信息
+ * @return
+ * DeviceInfo
+ */
+ DeviceInfo getStatus();
+
+ byte[] directBytes(byte[] data);
+}
diff --git a/src/main/java/com/sunyard/constant/SDFConstant.java b/src/main/java/com/sunyard/constant/SDFConstant.java
new file mode 100644
index 0000000..2873c77
--- /dev/null
+++ b/src/main/java/com/sunyard/constant/SDFConstant.java
@@ -0,0 +1,39 @@
+package com.sunyard.constant;
+
+/**
+ * SJJ1418指令的相关常量
+ */
+public class SDFConstant {
+
+ // ===========非对称算法=======
+ public static final int RSA_ALG = 0x00000100;
+
+ public static final int SM2_ALG = 0x00000200;
+
+ // =========对称算法===========
+ public static final int SM1_ALG = 0x00010000;
+ public static final int SSF33_ALG = 0x00020000;
+ public static final int SM4_ALG = 0x00040000;
+ public static final int DES_ALG = 0x00080000;
+ public static final int _3DES_ALG = 0x00100000;
+ public static final int IDEA_ALG = 0x00200000;
+ public static final int AES_ALG = 0x00400000;
+
+ // =========hash杂凑算法==========
+ public static final int SM3_ALG = 0x01000000;
+ public static final int SMA1_ALG = 0x02000000;
+ public static final int SMA256_ALG = 0x04000000;
+
+ // ========
+ public static final int _ECCref_MAX_BITS = 512;
+ public static final int _ECCref_MAX_LEN = ((_ECCref_MAX_BITS+7)/8);
+ public static final int _ECCref_MAX_DATALEN = 5120;
+
+ public static final int _RSAref_MAX_BITS = 2048;
+ public static final int _RSAref_MAX_LEN = ((_RSAref_MAX_BITS + 7)/8);
+ public static final int _RSAref_MAX_PBITS = ((_RSAref_MAX_BITS + 1)/2);
+ public static final int _RSAref_MAX_PLEN = ((_RSAref_MAX_PBITS + 7)/8);
+
+ public static final int SYD_PARA_SPONSORID_MAX = 256;
+
+}
diff --git a/src/main/java/com/sunyard/entity/DeviceInfo.java b/src/main/java/com/sunyard/entity/DeviceInfo.java
new file mode 100644
index 0000000..ed76607
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/DeviceInfo.java
@@ -0,0 +1,228 @@
+package com.sunyard.entity;
+
+import com.sunyard.proto.Util;
+import com.sunyard.util.DataUtil;
+
+/**
+ * 设备信息定义
+ */
+public class DeviceInfo {
+
+ /**
+ * 设备生产厂商名称
+ */
+ private String IssuerName;
+
+ /**
+ * 设备型号
+ */
+ private String DeviceName;
+
+ /**
+ * 设备编号,机具号
+ */
+ private String DeviceSerial;
+
+ /**
+ * 密码设备内部软件的版本号
+ */
+ private String DeviceVersion;
+
+ /**
+ * 密码设备支持的接口规范版本号
+ */
+ private String StandardVersion;
+
+ /**
+ * 支持的算法
+ */
+ private int AsymAlgAbility;
+
+ /**
+ * RSA算法的最大模长
+ */
+ private int RSAMoldHeight;
+
+ /**
+ * SM2算法的最大模长
+ */
+ private int SM2MoldHeight;
+
+ /**
+ * 所有支持的对称算法
+ */
+ private int SymAlgAbility;
+
+ /**
+ * 支持的杂凑算法
+ */
+ private int HashAlgAbility;
+
+ /**
+ * 支持的最大文件存储空间(单位字节)
+ */
+ private int BufferSize;
+
+ public DeviceInfo() {
+ }
+
+ /**
+ * 验证是否有传入的算法
+ * @param alg
+ * @return
+ */
+ public boolean isAlg(int alg){
+ return alg == (alg & AsymAlgAbility ) ||
+ alg == (alg & SymAlgAbility ) ||
+ alg == (alg & HashAlgAbility);
+ }
+
+ /**
+ * 53554E59415244000000000000000000000000000000000000000000000000000000000000000000 SUNYARD
+ * 53594431313138000000000000000000 SYD1118
+ * 71420200000630313030303030303031
+ * 322E3031 2.01
+ * 00182012 00182012
+ * 00000300 00030000
+ * 00010008 08000100
+ * 007F0000 00007F00
+ * 01000000 00000001
+ * 68020000 00000268
+ * 将传进来的byte[]数组解析成字段的值
+ * @param data
+ */
+ public DeviceInfo(byte[] data) {
+
+ this.IssuerName = new String(DataUtil.catFromArr(data, 0, DataUtil.getIndex(data, 0, 40)));
+
+ int index = DataUtil.getIndex(data, 40, 56);
+ this.DeviceName = new String(DataUtil.catFromArr(data, 40, index - 40));
+
+ this.DeviceSerial = Util.bytes2HexString(DataUtil.catFromArr(data, 56, 6));
+
+ this.DeviceVersion = new String(DataUtil.catFromArr(data, 72, 4));
+
+ this.StandardVersion = Util.bytes2HexString(DataUtil.catFromArr(data, 76, 4));
+
+ this.AsymAlgAbility = DataUtil.byteToInt4(data, 80);
+
+ this.SM2MoldHeight = (data[84] & 0xff) + ((data[85] & 0xff) << 8);
+
+ this.RSAMoldHeight = (data[86] & 0xff) + ((data[87] & 0xff) << 8);
+
+ this.SymAlgAbility = DataUtil.byteToInt4(data, 88);
+ this.HashAlgAbility = DataUtil.byteToInt4(data, 92);
+
+ byte[] bs = new byte[4];
+ for (int i = 0; i < 4; i++) {
+ bs[3 - i] = data[96 + i];
+ }
+ this.BufferSize = DataUtil.byteToInt4(bs, 0);
+ }
+
+
+ public String getIssuerName() {
+ return IssuerName;
+ }
+
+ public void setIssuerName(String issuerName) {
+ IssuerName = issuerName;
+ }
+
+ public String getDeviceName() {
+ return DeviceName;
+ }
+
+ public void setDeviceName(String deviceName) {
+ DeviceName = deviceName;
+ }
+
+ public String getDeviceSerial() {
+ return DeviceSerial;
+ }
+
+ public void setDeviceSerial(String deviceSerial) {
+ DeviceSerial = deviceSerial;
+ }
+
+ public String getDeviceVersion() {
+ return DeviceVersion;
+ }
+
+ public void setDeviceVersion(String deviceVersion) {
+ DeviceVersion = deviceVersion;
+ }
+
+ public String getStandardVersion() {
+ return StandardVersion;
+ }
+
+ public void setStandardVersion(String standardVersion) {
+ StandardVersion = standardVersion;
+ }
+
+ public int getAsymAlgAbility() {
+ return AsymAlgAbility;
+ }
+
+ public void setAsymAlgAbility(int asymAlgAbility) {
+ AsymAlgAbility = asymAlgAbility;
+ }
+
+ public int getRSAMoldHeight() {
+ return RSAMoldHeight;
+ }
+
+ public void setRSAMoldHeight(int RSAMoldHeight) {
+ this.RSAMoldHeight = RSAMoldHeight;
+ }
+
+ public int getSM2MoldHeight() {
+ return SM2MoldHeight;
+ }
+
+ public void setSM2MoldHeight(int SM2MoldHeight) {
+ this.SM2MoldHeight = SM2MoldHeight;
+ }
+
+ public int getSymAlgAbility() {
+ return SymAlgAbility;
+ }
+
+ public void setSymAlgAbility(int symAlgAbility) {
+ SymAlgAbility = symAlgAbility;
+ }
+
+ public int getHashAlgAbility() {
+ return HashAlgAbility;
+ }
+
+ public void setHashAlgAbility(int hashAlgAbility) {
+ HashAlgAbility = hashAlgAbility;
+ }
+
+ public int getBufferSize() {
+ return BufferSize;
+ }
+
+ public void setBufferSize(int bufferSize) {
+ BufferSize = bufferSize;
+ }
+
+ @Override
+ public String toString() {
+ return "DeviceInfo{" +
+ "IssuerName='" + IssuerName + '\'' +
+ ", DeviceName='" + DeviceName + '\'' +
+ ", DeviceSerial='" + DeviceSerial + '\'' +
+ ", DeviceVersion='" + DeviceVersion + '\'' +
+ ", StandardVersion='" + StandardVersion + '\'' +
+ ", AsymAlgAbility=" + AsymAlgAbility +
+ ", RSAMoldHeight=" + RSAMoldHeight +
+ ", SM2MoldHeight=" + SM2MoldHeight +
+ ", SymAlgAbility=" + SymAlgAbility +
+ ", HashAlgAbility=" + HashAlgAbility +
+ ", BufferSize=" + BufferSize +
+ '}';
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/ECCCipher_st.java b/src/main/java/com/sunyard/entity/ECCCipher_st.java
new file mode 100644
index 0000000..d5cc032
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/ECCCipher_st.java
@@ -0,0 +1,55 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class ECCCipher_st {
+
+ private byte[] x = new byte[ SDFConstant._ECCref_MAX_LEN ];
+ private byte[] y = new byte[ SDFConstant._ECCref_MAX_LEN ];
+ private byte[] M = new byte[ 32 ];
+ private int L;
+ private byte[] C = new byte[ SDFConstant._ECCref_MAX_DATALEN ]; // C不能大于5120字节
+
+ public ECCCipher_st() {
+ }
+
+ public byte[] getX() {
+ return x;
+ }
+
+ public void setX(byte[] x) {
+ this.x = x;
+ }
+
+ public byte[] getY() {
+ return y;
+ }
+
+ public void setY(byte[] y) {
+ this.y = y;
+ }
+
+ public byte[] getM() {
+ return M;
+ }
+
+ public void setM(byte[] m) {
+ M = m;
+ }
+
+ public int getL() {
+ return L;
+ }
+
+ public void setL(int l) {
+ L = l;
+ }
+
+ public byte[] getC() {
+ return C;
+ }
+
+ public void setC(byte[] c) {
+ C = c;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/ECCSignnature_st.java b/src/main/java/com/sunyard/entity/ECCSignnature_st.java
new file mode 100644
index 0000000..2e0f5b1
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/ECCSignnature_st.java
@@ -0,0 +1,28 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class ECCSignnature_st {
+
+ private byte[] r = new byte[ SDFConstant._ECCref_MAX_LEN ];
+ private byte[] s = new byte[ SDFConstant._ECCref_MAX_LEN ];
+
+ public ECCSignnature_st() {
+ }
+
+ public byte[] getR() {
+ return r;
+ }
+
+ public void setR(byte[] r) {
+ this.r = r;
+ }
+
+ public byte[] getS() {
+ return s;
+ }
+
+ public void setS(byte[] s) {
+ this.s = s;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/ECCrefPrivateKey_st.java b/src/main/java/com/sunyard/entity/ECCrefPrivateKey_st.java
new file mode 100644
index 0000000..cdf2faa
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/ECCrefPrivateKey_st.java
@@ -0,0 +1,29 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class ECCrefPrivateKey_st {
+
+ private int bits;
+
+ private byte[] K = new byte[ SDFConstant._ECCref_MAX_LEN ];
+
+ public ECCrefPrivateKey_st() {
+ }
+
+ public int getBits() {
+ return bits;
+ }
+
+ public void setBits(int bits) {
+ this.bits = bits;
+ }
+
+ public byte[] getK() {
+ return K;
+ }
+
+ public void setK(byte[] k) {
+ K = k;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/ECCrefPublicKey_st.java b/src/main/java/com/sunyard/entity/ECCrefPublicKey_st.java
new file mode 100644
index 0000000..0af274a
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/ECCrefPublicKey_st.java
@@ -0,0 +1,39 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class ECCrefPublicKey_st {
+
+ private int bits;
+
+ private byte[] x = new byte[ SDFConstant._ECCref_MAX_LEN ];
+
+ private byte[] y = new byte[ SDFConstant._ECCref_MAX_LEN ];
+
+ public ECCrefPublicKey_st() {
+ }
+
+ public int getBits() {
+ return bits;
+ }
+
+ public void setBits(int bits) {
+ this.bits = bits;
+ }
+
+ public byte[] getX() {
+ return x;
+ }
+
+ public void setX(byte[] x) {
+ this.x = x;
+ }
+
+ public byte[] getY() {
+ return y;
+ }
+
+ public void setY(byte[] y) {
+ this.y = y;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/RSArefPriKey_st.java b/src/main/java/com/sunyard/entity/RSArefPriKey_st.java
new file mode 100644
index 0000000..ff6b66a
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/RSArefPriKey_st.java
@@ -0,0 +1,73 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class RSArefPriKey_st {
+
+ private int bits;
+ private byte[] m = new byte[SDFConstant._RSAref_MAX_LEN];
+ private byte[] e = new byte[SDFConstant._RSAref_MAX_LEN];
+ private byte[] d = new byte[SDFConstant._RSAref_MAX_LEN];
+ private byte[][] prime = new byte[2][SDFConstant._RSAref_MAX_PLEN];
+ private byte[][] pexp = new byte[2][SDFConstant._RSAref_MAX_PLEN];
+ private byte[] coef = new byte[SDFConstant._RSAref_MAX_PLEN];
+
+ public RSArefPriKey_st() {
+ }
+
+ public int getBits() {
+ return bits;
+ }
+
+ public void setBits(int bits) {
+ this.bits = bits;
+ }
+
+ public byte[] getM() {
+ return m;
+ }
+
+ public void setM(byte[] m) {
+ this.m = m;
+ }
+
+ public byte[] getE() {
+ return e;
+ }
+
+ public void setE(byte[] e) {
+ this.e = e;
+ }
+
+ public byte[] getD() {
+ return d;
+ }
+
+ public void setD(byte[] d) {
+ this.d = d;
+ }
+
+ public byte[][] getPrime() {
+ return prime;
+ }
+
+ public void setPrime(byte[][] prime) {
+ this.prime = prime;
+ }
+
+ public byte[][] getPexp() {
+ return pexp;
+ }
+
+ public void setPexp(byte[][] pexp) {
+ this.pexp = pexp;
+ }
+
+ public byte[] getCoef() {
+ return coef;
+ }
+
+ public void setCoef(byte[] coef) {
+ this.coef = coef;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/RSArefPubKey_st.java b/src/main/java/com/sunyard/entity/RSArefPubKey_st.java
new file mode 100644
index 0000000..999554c
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/RSArefPubKey_st.java
@@ -0,0 +1,38 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class RSArefPubKey_st {
+
+ private int bits;
+
+ private byte[] m = new byte[SDFConstant._RSAref_MAX_LEN];
+ private byte[] e = new byte[SDFConstant._RSAref_MAX_LEN];
+
+ public RSArefPubKey_st() {
+ }
+
+ public int getBits() {
+ return bits;
+ }
+
+ public void setBits(int bits) {
+ this.bits = bits;
+ }
+
+ public byte[] getM() {
+ return m;
+ }
+
+ public void setM(byte[] m) {
+ this.m = m;
+ }
+
+ public byte[] getE() {
+ return e;
+ }
+
+ public void setE(byte[] e) {
+ this.e = e;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/SYD_AgreementHandle_st.java b/src/main/java/com/sunyard/entity/SYD_AgreementHandle_st.java
new file mode 100644
index 0000000..62ae3df
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/SYD_AgreementHandle_st.java
@@ -0,0 +1,64 @@
+package com.sunyard.entity;
+
+import com.sunyard.constant.SDFConstant;
+
+public class SYD_AgreementHandle_st {
+
+ private int index; //发起方公私钥索引
+ private int idlength; //发起方ID长度
+ private byte[] id = new byte[SDFConstant.SYD_PARA_SPONSORID_MAX]; //发起方ID
+ private ECCrefPublicKey_st pucPublicKey_sm2; //发起方临时公钥
+ private ECCrefPrivateKey_st pucPrivateKey_sm2; //发起方临时私钥
+ private int Key_len; //协商生成的密钥长度
+
+ public SYD_AgreementHandle_st() {
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public int getIdlength() {
+ return idlength;
+ }
+
+ public void setIdlength(int idlength) {
+ this.idlength = idlength;
+ }
+
+ public byte[] getId() {
+ return id;
+ }
+
+ public void setId(byte[] id) {
+ this.id = id;
+ }
+
+ public ECCrefPublicKey_st getPucPublicKey_sm2() {
+ return pucPublicKey_sm2;
+ }
+
+ public void setPucPublicKey_sm2(ECCrefPublicKey_st pucPublicKey_sm2) {
+ this.pucPublicKey_sm2 = pucPublicKey_sm2;
+ }
+
+ public ECCrefPrivateKey_st getPucPrivateKey_sm2() {
+ return pucPrivateKey_sm2;
+ }
+
+ public void setPucPrivateKey_sm2(ECCrefPrivateKey_st pucPrivateKey_sm2) {
+ this.pucPrivateKey_sm2 = pucPrivateKey_sm2;
+ }
+
+ public int getKey_len() {
+ return Key_len;
+ }
+
+ public void setKey_len(int key_len) {
+ Key_len = key_len;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/SYD_HashCtx_st.java b/src/main/java/com/sunyard/entity/SYD_HashCtx_st.java
new file mode 100644
index 0000000..3557230
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/SYD_HashCtx_st.java
@@ -0,0 +1,53 @@
+package com.sunyard.entity;
+
+public class SYD_HashCtx_st {
+
+ private byte[] hashContext = new byte[2048];
+ private int hashContextLen;
+ private byte[] hashMessage = new byte[2048];
+ private int hashMessageLen;
+ private int hashmode;
+
+ public SYD_HashCtx_st() {
+ }
+
+ public byte[] getHashContext() {
+ return hashContext;
+ }
+
+ public void setHashContext(byte[] hashContext) {
+ this.hashContext = hashContext;
+ }
+
+ public int getHashContextLen() {
+ return hashContextLen;
+ }
+
+ public void setHashContextLen(int hashContextLen) {
+ this.hashContextLen = hashContextLen;
+ }
+
+ public byte[] getHashMessage() {
+ return hashMessage;
+ }
+
+ public void setHashMessage(byte[] hashMessage) {
+ this.hashMessage = hashMessage;
+ }
+
+ public int getHashMessageLen() {
+ return hashMessageLen;
+ }
+
+ public void setHashMessageLen(int hashMessageLen) {
+ this.hashMessageLen = hashMessageLen;
+ }
+
+ public int getHashmode() {
+ return hashmode;
+ }
+
+ public void setHashmode(int hashmode) {
+ this.hashmode = hashmode;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/SYD_KeyHandle_st.java b/src/main/java/com/sunyard/entity/SYD_KeyHandle_st.java
new file mode 100644
index 0000000..d847372
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/SYD_KeyHandle_st.java
@@ -0,0 +1,26 @@
+package com.sunyard.entity;
+
+public class SYD_KeyHandle_st {
+
+ private int iKeylen;
+ private byte[] cKeyData = new byte[128];
+
+ public SYD_KeyHandle_st() {
+ }
+
+ public int getiKeylen() {
+ return iKeylen;
+ }
+
+ public void setiKeylen(int iKeylen) {
+ this.iKeylen = iKeylen;
+ }
+
+ public byte[] getcKeyData() {
+ return cKeyData;
+ }
+
+ public void setcKeyData(byte[] cKeyData) {
+ this.cKeyData = cKeyData;
+ }
+}
diff --git a/src/main/java/com/sunyard/entity/SYD_SessionKey_st.java b/src/main/java/com/sunyard/entity/SYD_SessionKey_st.java
new file mode 100644
index 0000000..f5c7f2a
--- /dev/null
+++ b/src/main/java/com/sunyard/entity/SYD_SessionKey_st.java
@@ -0,0 +1,26 @@
+package com.sunyard.entity;
+
+public class SYD_SessionKey_st {
+
+ private int iStatus;
+ private SYD_KeyHandle_st hKeyHandle;
+
+ public SYD_SessionKey_st() {
+ }
+
+ public int getiStatus() {
+ return iStatus;
+ }
+
+ public void setiStatus(int iStatus) {
+ this.iStatus = iStatus;
+ }
+
+ public SYD_KeyHandle_st gethKeyHandle() {
+ return hKeyHandle;
+ }
+
+ public void sethKeyHandle(SYD_KeyHandle_st hKeyHandle) {
+ this.hKeyHandle = hKeyHandle;
+ }
+}
diff --git a/src/main/java/com/sunyard/util/DataUtil.java b/src/main/java/com/sunyard/util/DataUtil.java
new file mode 100644
index 0000000..719dd27
--- /dev/null
+++ b/src/main/java/com/sunyard/util/DataUtil.java
@@ -0,0 +1,61 @@
+package com.sunyard.util;
+
+public class DataUtil {
+
+ /**
+ * 遍历数组,查找值为0的下标的位置
+ * @param data 数组
+ * @param start 开始的位置
+ * @param end 结束的位置
+ * @return
+ */
+ public static int getIndex(byte[] data, int start, int end) {
+ int index = 0;
+ for (int i = start; i < end; i++) {
+ if (data[i] == 0) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * 将data转为int类型
+ * @param data byte数组
+ * @return
+ */
+ public static int byteToInt4(byte[] data) {
+ return byteToInt4(data, 0);
+ }
+
+ /**
+ * 计算data从start位置开始后4位转为int类型。
+ * @param data byte数组
+ * @param start 起始位置
+ * @return
+ */
+ public static int byteToInt4(byte[] data, int start) {
+ // &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
+ int v0 = (data[start] & 0xff) << 24;
+ int v1 = (data[start + 1] & 0xff) << 16;
+ int v2 = (data[start + 2] & 0xff) << 8;
+ int v3 = (data[start + 3] & 0xff) ;
+ return v0 + v1 + v2 + v3;
+ }
+
+ /**
+ * 从data中以start为起始位置拷贝len长度的值
+ * @param data byte数组
+ * @param start 起始位置
+ * @param len 截取长度
+ * @return
+ */
+ public static byte[] catFromArr(byte[] data, int start, int len) {
+
+ byte[] rData = new byte[len];
+ System.arraycopy(data, start, rData, 0, len);
+
+ return rData;
+ }
+}
diff --git a/src/main/java/racal/sunyard/main/SydApiSDF4j.java b/src/main/java/racal/sunyard/main/SydApiSDF4j.java
new file mode 100644
index 0000000..509e24f
--- /dev/null
+++ b/src/main/java/racal/sunyard/main/SydApiSDF4j.java
@@ -0,0 +1,381 @@
+package racal.sunyard.main;
+
+import com.sunyard.SydApiException;
+import com.sunyard.SydApiSDF;
+import com.sunyard.entity.DeviceInfo;
+import com.sunyard.proto.Packet;
+import com.sunyard.proto.PacketSection;
+import com.sunyard.proto.Util;
+import com.sunyard.trans.PacketSN;
+import racal.sunyard.main.proto.Proto0100;
+import racal.sunyard.main.proto.Proto0101;
+import racal.sunyard.main.proto.ProtoSK;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SydApiSDF4j implements SydApiSDF {
+
+ private static boolean debug = false;
+
+ private static long sTime = System.currentTimeMillis();
+
+ private static String ip1;
+ private static String ip2;
+ private static int port;
+ private static int timeout;
+
+ private Socket socket;
+
+ //初始化变量
+ static {
+
+ String d = System.getProperty("com.sunyard.sydapi4j.debug");
+ if ("true".equals(d)) {
+ debug = true;
+ }
+ }
+
+ private static void println(Object i) {
+ if (debug) {
+ System.out.println(i);
+ }
+
+ }
+
+ private static void print(Object i) {
+ if (debug) {
+ System.out.print(i);
+ }
+
+ }
+
+ //gc回收
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ if (null != this.socket) {
+ this.socket.close();
+ }
+ }
+
+ /**
+ * 确认链接可用
+ * 确认读缓存为空
+ */
+ private void testSocket() {
+
+ // 就是简单对象模式,链接长短完全由用户自己控制
+ if (null == socket) {
+
+ // 全局热备模式(old shool)
+ if (null != ip2) {
+
+ Socket s1 = new Socket();
+ SocketAddress address = new InetSocketAddress(ip1, port);
+
+ try {
+ s1.connect(address, timeout);
+ socket = s1;
+ socket.setSoTimeout(timeout);
+ } catch (Exception e) {
+ Socket s2 = new Socket();
+ SocketAddress add2 = new InetSocketAddress(ip2, port);
+ try {
+ s2.connect(add2, timeout);
+ socket = s2;
+ socket.setSoTimeout(timeout);
+ } catch (Exception e2) {
+ throw new SydApiException(-2);
+ }
+ }
+
+ }
+ }
+
+ clear();
+
+ }
+
+ protected byte[] syncSend(ByteBuffer bb) {
+
+
+ byte[] buff;
+ if (bb.position() == bb.limit()) {
+ buff = bb.array();
+ } else {
+ buff = new byte[bb.position()];
+ System.arraycopy(bb.array(), 0, buff, 0, buff.length);
+ }
+
+
+ println("\n\n发送数据");
+ print("HEX数据: \t");
+ println(Util.bytes2HexString(buff));
+
+ testSocket();
+
+ try {
+ socket.getOutputStream().write(buff);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return buff;
+ }
+
+ private void clear() {
+ try {
+ InputStream is = socket.getInputStream();
+ while (is.available() > 0) {
+ is.read();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ private ByteBuffer read(Socket socket) throws IOException {
+ InputStream is = socket.getInputStream();
+ int d;
+ int high = is.read();
+ int low = is.read();
+ int len = (high << 8) + low;
+
+ len += 2;
+
+ print("H\t");
+ println(Integer.toHexString(high));
+ print("L\t");
+ println(Integer.toHexString(low));
+ print("Len\t");
+ println(len);
+
+
+ ByteBuffer bb = ByteBuffer.allocate(len);
+ bb.put((byte) (high & 0xFF));
+ bb.put((byte) (low & 0xFF));
+
+ while (true) {
+ d = is.read();
+ if (-1 == d) {
+ break;
+ }
+
+ bb.put((byte) (d & 0xFF));
+
+ if (bb.position() == len) {
+ break;
+ }
+ }
+
+ print("HEX数据: \t");
+ println(Util.bytes2HexString(bb.array()));
+ return bb;
+ }
+
+ /**
+ * 阻塞读取
+ * 前两个字节是长度
+ *
+ * @return
+ * @buffer 如果出错,需要补发的数据。
+ */
+ protected ByteBuffer syncRead(byte[] buffer) {
+ println("\n\n接收数据");
+ try {
+ // 正常接收
+ ByteBuffer bb = read(socket);
+ return bb;
+
+ } catch (SocketTimeoutException e) {
+ throw new SydApiException("接收数据超时", -2);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ throw new SydApiException("通信数据错误", -3);
+ }
+
+ @Override
+ synchronized public SydApiSDF connect(String ip, int port, String pwd, int timeout) {
+
+ if (null != ip2) {
+ throw new SydApiException("双机热备模式不用调用此方法", -1);
+ }
+ Socket socket = new Socket();
+ SocketAddress address = new InetSocketAddress(ip, port);
+
+ try {
+ if (timeout > 0) {
+ socket.connect(address, timeout);
+ } else {
+ socket.connect(address);
+ }
+ socket.setSoTimeout(timeout);
+ } catch (Exception e) {
+ throw new SydApiException(-2);
+ }
+
+ this.socket = socket;
+ return this;
+ }
+
+ @Override
+ synchronized public SydApiSDF connect(String ip, int port, String pwd, int connectTimeout, int readTimeout) {
+
+ if (null != ip2) {
+ throw new SydApiException("双机热备模式不用调用此方法", -1);
+ }
+ Socket socket = new Socket();
+ SocketAddress address = new InetSocketAddress(ip, port);
+
+ try {
+ socket.connect(address, connectTimeout);
+ socket.setSoTimeout(readTimeout);
+ } catch (Exception e) {
+ throw new SydApiException(-2);
+ }
+
+ this.socket = socket;
+ return this;
+ }
+
+ @Override
+ synchronized public int disconnect() {
+
+ if (null != socket) {
+ try {
+ socket.getInputStream().close();
+ } catch (Exception e1) {
+ }
+
+
+ try {
+ socket.getOutputStream().close();
+ } catch (Exception e2) {
+ }
+
+ try {
+ socket.close();
+ } catch (Exception e) {
+ }
+
+ }
+
+ return 0;
+ }
+
+ @Override
+ public DeviceInfo getStatus() {
+
+ Proto0100 proto = new Proto0100();
+
+ HashMap packet = new HashMap();
+ HashMap data = new HashMap();
+ PacketSN sn = PacketSN.gen();
+ packet.put("header", sn.getSn().array());
+ packet.put("data", data);
+
+ // 渲染发送
+ 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");
+ byte[] be = error.getBytes();
+ if ((0 != (be[0] ^ be[1]))) {
+ throw new SydApiException(error.getInfo(), error.autoInt());
+ }
+
+ byte[] deviceinfo = ((PacketSection) ret.get("deviceinfo")).getBytes();
+
+ return new DeviceInfo(deviceinfo);
+ }
+
+ @Override
+ public byte[] directBytes(byte[] data) {
+ //初始化一个和byte长度一样的bb
+ ByteBuffer bb = ByteBuffer.allocate(data.length);
+ // 数组放到bb中
+ bb.put(data);
+
+ //发送数据,解析
+ synchronized (this) {
+ bb = syncRead(syncSend(bb));
+ }
+ //重置 limit 和postion 值
+ bb.flip();
+ //获取bb中有效大小
+ int len = bb.limit() - bb.position();
+
+ byte[] bytes = new byte[len];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = bb.get();
+ }
+ return bytes;
+ }
+
+ /**
+ * 获取随机数
+ * @param randLen 随机数长度
+ * @return
+ */
+ public byte[] genRandom(int randLen) {
+ //获取协议
+ Proto0101 proto = new Proto0101();
+
+ //填充数据
+ PacketSN sn = PacketSN.gen();
+ HashMap packet = new HashMap();
+ packet.put("header", sn.getSn().array());
+ HashMap data = new HashMap();
+ data.put("randLen", randLen);
+ packet.put("data", data);
+
+ //渲染发送
+ 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());
+ }
+
+ return ((PacketSection) ret.get("randData")).getBytes();
+ }
+}
diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
index d0ae978..18f46dc 100644
--- a/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
+++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethods.java
@@ -13,6 +13,7 @@ import org.junit.Test;
import racal.sunyard.main.SydApi4j;
import java.io.*;
+import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
@@ -2481,5 +2482,14 @@ public class TestAllMethods {
}
}
}
+
+ @Test
+ public void getAllMethod() {
+ Method[] methods = SydApi4j.class.getDeclaredMethods();
+ for (Method method : methods) {
+ Class> returnType = method.getReturnType();
+
+ }
+ }
}
diff --git a/src/test/java/com/sunyard/sydapi/test/TestAllMethodsSDF.java b/src/test/java/com/sunyard/sydapi/test/TestAllMethodsSDF.java
new file mode 100644
index 0000000..5776d8a
--- /dev/null
+++ b/src/test/java/com/sunyard/sydapi/test/TestAllMethodsSDF.java
@@ -0,0 +1,60 @@
+package com.sunyard.sydapi.test;
+
+import com.sunyard.constant.SDFConstant;
+import com.sunyard.entity.DeviceInfo;
+import com.sunyard.proto.Util;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import racal.sunyard.main.SydApiSDF4j;
+
+public class TestAllMethodsSDF {
+
+ SydApiSDF4j api;
+
+ @Before
+ public void before() {
+ // 通过设置debug的属性开启debug,如果不设置则默认不打开
+ System.setProperty("com.sunyard.sydapi4j.debug", "true");
+ api = (SydApiSDF4j) new SydApiSDF4j().connect("192.168.2.8", 8889, null, 1000);
+ }
+
+ @After
+ public void after() {
+ try {
+ this.api.disconnect();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // 测试通过
+ // 0100
+ @Test
+ public void testGetStatus1() {
+ DeviceInfo deviceInfo = api.getStatus();
+
+ System.out.println(deviceInfo);
+
+ // 验证是否含有该算法
+ System.out.println(deviceInfo.isAlg(SDFConstant.RSA_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SM2_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SM1_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SSF33_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SM4_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.DES_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant._3DES_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.IDEA_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.AES_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SM3_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SMA1_ALG));
+ System.out.println(deviceInfo.isAlg(SDFConstant.SMA256_ALG));
+ }
+
+ @Test
+ public void testGenRandom() {
+ byte[] bytes = api.genRandom(8);
+ System.out.println(Util.bytes2HexString(bytes));
+ }
+
+}