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)); + } + +}