1、添加SJJ1418相关的一些结构体。2、添加SJJ1418指令相关的部分xml文件。3、添加SJJ1418接口的实现类。
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, Object> packet = new HashMap<String, Object>();
|
||||
HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
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<String, Object> ret = p.toMap();
|
||||
|
||||
if (
|
||||
!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
|
||||
) {
|
||||
throw new SydApiException("包序号不匹配", -4);
|
||||
}
|
||||
|
||||
ret = (Map<String, Object>) 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<String, Object> packet = new HashMap<String, Object>();
|
||||
packet.put("header", sn.getSn().array());
|
||||
HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
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<String, Object> ret = p.toMap();
|
||||
if (
|
||||
!Arrays.equals(sn.getSn().array(), ((PacketSection) ret.get("header")).getBytes())
|
||||
) {
|
||||
throw new SydApiException("包序号不匹配", -4);
|
||||
}
|
||||
ret = (Map<String, Object>) 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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user