init files
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package com.sunyard;
|
||||
|
||||
import com.sunyard.proto.Util;
|
||||
import racal.sunyard.main.SydApi4j;
|
||||
|
||||
import java.security.Key;
|
||||
|
||||
public class DaToSHCA {
|
||||
|
||||
private SydApi key;
|
||||
private da_handle daHandle;
|
||||
public boolean DA_OpenHsmServer(da_handle daHandle, String IP,int Port){
|
||||
try {
|
||||
SydApi key = new SydApi4j().connect(IP,Port,null,10000);
|
||||
this.key= key;
|
||||
}catch (SydApiException e){
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean DA_CloseHsmServer (da_handle daHandle){
|
||||
int disconnect = key.disconnect();
|
||||
if (disconnect == 0){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Key DA_GetSM2PublicKey(da_handle daHandle, int keyNum){
|
||||
|
||||
// final String s = key.SM2GetPublicKeyC("" + keyNum, 0);
|
||||
|
||||
final String s = key.SM2GetPublicKeyC_QX(keyNum, 0);
|
||||
|
||||
return new Key() {
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return Util.hexString2Bytes(s);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public void SM3_Init(da_handle daHandle, byte[] pubKey){
|
||||
this.daHandle = daHandle;
|
||||
RetWrap retWrap = key.SM3Hash(1, "1234567812345678", new byte[0], new byte[0], new byte[0]);
|
||||
byte[] filterData = (byte[])retWrap.get("filterData");
|
||||
daHandle.setFilterData(filterData);
|
||||
}
|
||||
|
||||
public void SM3_Updata(da_handle daHandle, byte[] InData){
|
||||
byte[] filterData = daHandle.getFilterData();
|
||||
RetWrap retWrap = key.SM3Hash(2, "",new byte[0], InData, filterData);
|
||||
filterData = (byte[])retWrap.get("filterData");
|
||||
daHandle.setFilterData(filterData);
|
||||
}
|
||||
|
||||
public byte[] SM3_Final(da_handle daHandle){
|
||||
byte[] filterData = daHandle.getFilterData();
|
||||
RetWrap retWrap = key.SM3Hash(3, "",new byte[0], new byte[0], filterData);
|
||||
byte[] hash = (byte[])retWrap.get("hash");
|
||||
return hash;
|
||||
}
|
||||
|
||||
public byte[] DA_SM2Sgin(da_handle daHandle, int keyNum, byte[] InData){
|
||||
|
||||
byte[] s = key.detachedSign(0,InData,keyNum);
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean DA_SM2Verify(da_handle daHandle, byte[] InData, String SignData, byte[] sm2Pub){
|
||||
|
||||
return key.detachedVerify(0, InData, SignData.getBytes());
|
||||
}
|
||||
|
||||
public static class da_handle{
|
||||
public da_handle(){
|
||||
super();
|
||||
}
|
||||
private byte[] filterData;
|
||||
|
||||
public void setFilterData(byte[] filterData) {
|
||||
this.filterData = filterData;
|
||||
}
|
||||
|
||||
public byte[] getFilterData() {
|
||||
return filterData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.sunyard;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 包装多返回值
|
||||
*/
|
||||
public class RetWrap extends HashMap<String, Object>{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.sunyard;
|
||||
|
||||
|
||||
import com.sunyard.inf.*;
|
||||
import com.sunyard.inf.customize.SydHAApi;
|
||||
import com.sunyard.inf.customize.SydQNUCApi;
|
||||
import com.sunyard.inf.customize.SydSDNXApi;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Created by Cheney on 2017/11/11.
|
||||
* 程序调用接口
|
||||
*/
|
||||
public interface SydApi extends SydRawApi, SydCertApi, SydCryptionApi, SydGenApi, SydSVApi, SydHAApi, SydQNUCApi, SydPledge, SydPINOpt {
|
||||
|
||||
byte ALG_AES = 0x30;
|
||||
byte ALG_SM4 = 0x31;
|
||||
int NALG_3DES = 0x00;
|
||||
int NALG_SM4 = 0x01;
|
||||
int NALG_AES = 0x02;
|
||||
|
||||
String RET_CIPHER_KEY = "CipherKey";
|
||||
String RET_SESSION_KEY = "SessionKey";
|
||||
String RET_PUBLIC_KEY = "PublicKey";
|
||||
String RET_PRIVATE_KEY = "PrivateKey";
|
||||
String RET_KCV = "KCV";
|
||||
|
||||
|
||||
int FOR_SIGN = 0;
|
||||
int FOR_ENCRYPT = 1;
|
||||
|
||||
int DATA_HASH = 0;
|
||||
int DATA_ORIGIN = 1;
|
||||
|
||||
|
||||
byte KCV_S = 0x53;
|
||||
|
||||
/**
|
||||
* 建立到指定地址和端口号的加密设备的TCP/IP 连接,返回 TCP/IP 连接句柄。
|
||||
* 如果采用短连接,交易结束,要调用 disconnect() 进行释放连接。
|
||||
* @param ip 加密设备的 IP 地址。
|
||||
* @param port 加密设备的端口号。
|
||||
* @param pwd 保留。
|
||||
* @param timeout 超时时间。
|
||||
* @return 设备操作对象
|
||||
*/
|
||||
SydApi 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 设备操作对象
|
||||
*/
|
||||
SydApi connect(String ip, int port, String pwd, int connectTimeout, int readTimeout);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 断开连接
|
||||
* @return 0 表示成功;非 0 表示失败;
|
||||
*/
|
||||
int disconnect();
|
||||
|
||||
|
||||
// 方便链接池扩展
|
||||
// 单例可以不实现
|
||||
void free();
|
||||
|
||||
// 方便链接池扩展
|
||||
// 单例可以不实现
|
||||
void error();
|
||||
|
||||
|
||||
/**
|
||||
* 获取加密机状态
|
||||
* @return CPU/MEM/DISK
|
||||
*/
|
||||
RetWrap getStatus();
|
||||
|
||||
byte[] directBytes(byte[] data);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.sunyard;
|
||||
|
||||
import com.sunyard.proto.Util;
|
||||
|
||||
/**
|
||||
* Created by Cheney on 2017/8/3.
|
||||
*/
|
||||
public class SydApiException extends RuntimeException{
|
||||
private int retCode;
|
||||
private String msg;
|
||||
|
||||
public int getRetCode() {
|
||||
return retCode;
|
||||
}
|
||||
|
||||
|
||||
public void transMsg(){
|
||||
switch (this.retCode){
|
||||
case -1:
|
||||
case -2:
|
||||
case -3:
|
||||
this.msg = "网络错误";
|
||||
break;
|
||||
case -4:
|
||||
this.msg = "返回包的序列号有误";
|
||||
break;
|
||||
case -5:
|
||||
this.msg = "返回包的命令码有误";
|
||||
break;
|
||||
case -6:
|
||||
this.msg = "输出缓冲区预留太小";
|
||||
break;
|
||||
case -25:
|
||||
this.msg = "输入的 HASH 值长度应该为 32 个字节";
|
||||
break;
|
||||
case -26:
|
||||
this.msg = "用户标识超长(应该<=16) ";
|
||||
break;
|
||||
case -27:
|
||||
this.msg = "数据类型不合法 ";
|
||||
break;
|
||||
case 33:
|
||||
this.msg = "检索的数据或密钥不存在";
|
||||
break;
|
||||
case 4:
|
||||
this.msg = "DER 编码格式错误(公钥) ";
|
||||
break;
|
||||
case 21:
|
||||
this.msg = "输入的数据格式错误 ";
|
||||
break;
|
||||
case 19:
|
||||
this.msg = "数据解密错(C3) ";
|
||||
break;
|
||||
case 2:
|
||||
this.msg = "签名验证错误 ";
|
||||
break;
|
||||
|
||||
case 32770:
|
||||
this.msg = "签名验证错误(P7) ";
|
||||
break;
|
||||
|
||||
case 32773:
|
||||
this.msg = "证书不可信";
|
||||
break;
|
||||
|
||||
case 32884:
|
||||
this.msg = "证书或签名数据的格式错";
|
||||
break;
|
||||
|
||||
case 36868:
|
||||
this.msg = "DN 所指向的实体不存在";
|
||||
break;
|
||||
|
||||
case 40000:
|
||||
this.msg = "输入的大数据处理异常";
|
||||
|
||||
default:
|
||||
this.msg = "未定义的错误";
|
||||
}
|
||||
}
|
||||
|
||||
public SydApiException(int retCode) {
|
||||
this.retCode = retCode;
|
||||
transMsg();
|
||||
}
|
||||
|
||||
|
||||
public SydApiException(String msg, int ret){
|
||||
this(ret);
|
||||
if (null == msg || "".equals(msg)){
|
||||
transMsg();
|
||||
}else {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
|
||||
public static SydApiException fromBin( byte[] b , String msg){
|
||||
int code = null != b && b[0] >= 48 && b[0] <= 57 ? Util.a2i( b , 10) : Util.b2i( b );
|
||||
return new SydApiException(msg, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(SydApiException.class.getName());
|
||||
sb.append(" : ");
|
||||
sb.append("code = ");
|
||||
sb.append(this.retCode);
|
||||
sb.append(" ( 0x");
|
||||
sb.append(Integer.toHexString(this.retCode));
|
||||
sb.append(" ) ");
|
||||
sb.append(" msg = ");
|
||||
sb.append(this.msg);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.sunyard.cert;
|
||||
|
||||
import com.sunyard.proto.Util;
|
||||
|
||||
public class Cert extends CertInfo {
|
||||
|
||||
// 公钥数据
|
||||
private byte[] pubKey;
|
||||
|
||||
|
||||
public byte[] getPubKey() {
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
public void setPubKey(byte[] pubKey) {
|
||||
this.pubKey = pubKey;
|
||||
}
|
||||
|
||||
public void setPubKey(byte[] pubKey, int offsize, int len) {
|
||||
int l = (0xFF & pubKey[offsize]) * 256 + (0xFF & pubKey[offsize + 1]);
|
||||
|
||||
byte[] pk = new byte[ l ];
|
||||
System.arraycopy(pubKey, offsize + 2, pk , 0, l);
|
||||
this.pubKey = Util.hexString2Bytes(new String(pk));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.sunyard.cert;
|
||||
|
||||
public class CertInfo extends Info {
|
||||
|
||||
private String cert;
|
||||
|
||||
public String getCert() {
|
||||
return cert;
|
||||
}
|
||||
|
||||
public void setCert(String cert) {
|
||||
this.cert = cert;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.sunyard.cert;
|
||||
|
||||
import com.sunyard.proto.Util;
|
||||
|
||||
/**
|
||||
* Created by Ztt on 2017/8/3.
|
||||
*/
|
||||
abstract public class Info {
|
||||
// 颁发者 DN
|
||||
private String issuer;
|
||||
// 证书序列号
|
||||
private String serialNumber;
|
||||
// 证书主题
|
||||
private String subject;
|
||||
// 证书有效期的起始时间
|
||||
private String notBefore;
|
||||
// 证书有效期的终止时间
|
||||
private String notAfter;
|
||||
|
||||
|
||||
public String getIssuer() {
|
||||
return issuer;
|
||||
}
|
||||
|
||||
public void setIssuer(String issuer) {
|
||||
this.issuer = issuer;
|
||||
}
|
||||
|
||||
public String getSerialNumber() {
|
||||
return serialNumber;
|
||||
}
|
||||
|
||||
public void setSerialNumber(String serialNumber) {
|
||||
this.serialNumber = serialNumber;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
||||
public void setNotBefore(String notBefore) {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public String getNotAfter() {
|
||||
return notAfter;
|
||||
}
|
||||
|
||||
public void setNotAfter(String notAfter) {
|
||||
this.notAfter = notAfter;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.sunyard.cert;
|
||||
|
||||
/**
|
||||
* Created by Ztt on 2017/8/3.
|
||||
*/
|
||||
public class X509 extends Cert {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
|
||||
import com.sunyard.cert.X509;
|
||||
|
||||
/**
|
||||
* 证书操作相关接口
|
||||
*/
|
||||
public interface SydCertApi {
|
||||
/**
|
||||
* 通过证书的 DN,获取证书的序号。
|
||||
* @param nCertType 输入 证书类型,0x00:签名证书,0x01:加密证书
|
||||
* @param certDN 输入。证书 subject 的 DN。
|
||||
* @return CertSerial 证书有 SN。
|
||||
*/
|
||||
String getX509SN(
|
||||
int nCertType,
|
||||
byte[] certDN
|
||||
);
|
||||
|
||||
/**
|
||||
* 通过证书 获得 DER编码的公钥。
|
||||
* @param dnType 证书类型 0:签名证书, 1:加密证书
|
||||
* @param dn 传入的证书
|
||||
* @return 输出的公钥串,DER 编码,HEX 格式。输出的公钥串,DER 编码,HEX 格式。
|
||||
*/
|
||||
String GetDNPublicKey(
|
||||
int dnType,
|
||||
byte[] dn
|
||||
);
|
||||
|
||||
/**
|
||||
* 通过使用者 ID 获得使用者的 SM2 公钥(DER 编码)。
|
||||
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
|
||||
* @param nKeyTypes 密钥类型,0x00:签名公钥, 0x01:加密公钥。
|
||||
* @return 输出的公钥串,DER 编码,HEX 格式。输出的公钥串,DER 编码,HEX 格式。
|
||||
*/
|
||||
String SM2GetPublicKeyC(
|
||||
String userId,
|
||||
int nKeyTypes
|
||||
);
|
||||
|
||||
String SM2GetPublicKeyC_QX(
|
||||
int userId,
|
||||
int nKeyTypes
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 输入 X509 格式的证书,获取证书信息。
|
||||
* @param pCert base64 编码的证书
|
||||
* @return 证书信息类
|
||||
*/
|
||||
X509 GetX509CertInfo(
|
||||
String pCert
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 通过使用者 ID 获取的 X509 证书文件。
|
||||
* @param userId 使用者的 ID,最大长度为 16 位数字(要与生成实体的机构号保持一致)。
|
||||
* @param nCertType 证书类型,0x00:签名证书, 0x01:加密证书
|
||||
* @return base64 编码的证书
|
||||
*/
|
||||
String GetX509CertFileC(
|
||||
String userId,
|
||||
int nCertType
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 从签名中获取证书
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @return 证书信息(包含公钥字段)
|
||||
*/
|
||||
public X509 SYD_Get_X509_CertInfo_HA(
|
||||
byte[] orgData,
|
||||
String sign
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
/**
|
||||
* 对称加解密相关接口
|
||||
*/
|
||||
|
||||
public interface SydCryptionApi extends SydSYMApi, SydASYMApi, SydHashApi {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hash 算法接口
|
||||
*/
|
||||
interface SydHashApi {
|
||||
|
||||
/**
|
||||
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
|
||||
*
|
||||
* @param publicKey 公钥(可以为空)
|
||||
* @param data 原始数据
|
||||
* @param mac 上一轮 mac 值
|
||||
* @return HASH 值,32 个 Bytes.
|
||||
*/
|
||||
byte[] SM3Hash(String publicKey, byte[] data, int i, byte[] mac);
|
||||
|
||||
|
||||
/**
|
||||
* 输入对指定的原始数据和公钥,通过 SM3 算法计算数据的散列值。
|
||||
*
|
||||
* @param publicKey 公钥(可以为空)
|
||||
* @param data 原始数据
|
||||
* @return HASH 值,32 个 Bytes.
|
||||
*/
|
||||
byte[] SM3Hash(String publicKey, byte[] data);
|
||||
|
||||
|
||||
/**
|
||||
* 输入对指定的原始数据 (无公钥),通过 SM3 算法计算数据的散列值。
|
||||
*
|
||||
* @param data 原始数据
|
||||
* @return HASH 值,32 个 Bytes.
|
||||
*/
|
||||
byte[] SM3Hash(byte[] data);
|
||||
|
||||
|
||||
public byte[] MACCalc(int alg, int keyType, int fullmode, int maclen, String key, byte[] infoData);
|
||||
|
||||
/**
|
||||
* mac 计算
|
||||
* @param alg 0=DES 1=3DES 2=SM4 3=AES 4=IDEA 5=SM1 6=3DES-X9.19
|
||||
* @param keyType 0-TAK 1-ZAK
|
||||
* @param fullMode 0-弱填充 1 强填充
|
||||
* @param AK 密钥
|
||||
* @param infoData <=1024
|
||||
* @param macLen 1=4Byte 2=8Byte 3=16Byte(仅在SM4/AES 下有效)
|
||||
* @return mac 值 hex 格式
|
||||
*/
|
||||
public String MACCalc(int alg, int keyType, String AK, int fullMode, byte[] infoData, int macLen);
|
||||
public void MACCheck(int alg, int keyType, String AK, int fullMode, byte[] infoData, String mac);
|
||||
|
||||
public String calcPBOCMAC(int mode, int keyType, String key, byte[] data, int block, byte[] iv);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 非对称加解密接口
|
||||
*/
|
||||
interface SydASYMApi {
|
||||
/**
|
||||
* 用指定的 SM2 公钥对指定的密文数据进行加密。
|
||||
*
|
||||
* @param publicKey 公钥钥串,DER 编码,HEX 格式。
|
||||
* @param pOrgData 加密的数据。
|
||||
* @return 加密的数据 base64 编码。
|
||||
*/
|
||||
String SM2Encrypt(
|
||||
byte[] publicKey,
|
||||
byte[] pOrgData
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 通过使用者 ID 所对应的私钥对指定的密文数据进行解密。
|
||||
*
|
||||
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
|
||||
* @param pEnData 加密的数据,base64 编码。
|
||||
* @return 明文数据。
|
||||
*/
|
||||
byte[] SM2DecryptC(
|
||||
String userId,
|
||||
String pEnData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对称加解密接口
|
||||
*/
|
||||
interface SydSYMApi {
|
||||
|
||||
public byte[] SYMEnDeData(Boolean isEn, int nAlg, String seesionKey, int roundmod, int fullMode, byte[] pInData, byte[] iv, int block);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用输入的会话密钥,对指定报文数据进行加密处理。
|
||||
*
|
||||
* @param nAlg 算法标识.,0x00:3DES,0x01:SM4。
|
||||
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
|
||||
* @param pINdata 要加密的报文明文。必须是 8 或16 的倍数。
|
||||
* @return 输出的报文密文, 长度为报文明文 + 16
|
||||
*/
|
||||
byte[] SYMEncryptData(int nAlg, String seesionKey, byte[] pINdata);
|
||||
byte[] SYMEncryptData(int nAlg, String seesionKey, int fullmode, byte[] pINdata);
|
||||
|
||||
byte[] SYMEncryptData_nofill(int nAlg, String seesionKey, byte[] pInData);
|
||||
|
||||
|
||||
/**
|
||||
* 用输入的会话密钥,对指定报文数据进行解密处理。
|
||||
*
|
||||
* @param nAlg 算法标识.,0x00:3DES,0x01:SM4。
|
||||
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
|
||||
* @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数。
|
||||
* @return 输出的报文明文。
|
||||
*/
|
||||
byte[] SYMDecryptData(int nAlg, String seesionKey, byte[] pINdata);
|
||||
byte[] SYMDecryptData(int nAlg, String seesionKey, int fullmode, byte[] pINdata);
|
||||
|
||||
byte[] SYMDecryptData_nofill(int nAlg, String seesionKey, byte[] pInData);
|
||||
|
||||
boolean SYMDecryptDataWithFile(int nAlg, String seesionKey, String inputPath, String outputPath) throws Exception;
|
||||
|
||||
/**
|
||||
* 用输入的会话密钥,对指定报文数据进行加密处理。
|
||||
*
|
||||
* @param nAlg 算法标识.,0x00:3DES,0x01:SM4。
|
||||
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
|
||||
* @param pINdata 要加密的报文明文。必须是 8 或16 的倍数。
|
||||
* @return 输出的报文密文, 长度为报文明文 + 16
|
||||
*/
|
||||
byte[] SYMEncryptDataCBC(int nAlg, String seesionKey, byte[] pINdata);
|
||||
public byte[] SYMEncryptDataCBC(int nAlg, String seesionKey, int fullmode, byte[] pInData);
|
||||
|
||||
/**
|
||||
* 用输入的会话密钥,对指定报文数据进行解密处理。
|
||||
*
|
||||
* @param nAlg 算法标识.,0x00:3DES,0x01:SM4。
|
||||
* @param seesionKey 本地LMK 加密的会话密钥,HEX 格式
|
||||
* @param pINdata 要解密的报文密文。长度必须是8 或16 的倍数。
|
||||
* @return 输出的报文明文。
|
||||
*/
|
||||
byte[] SYMDecryptDataCBC(int nAlg, String seesionKey, byte[] pINdata);
|
||||
public byte[] SYMDecryptDataCBC(int nAlg, String seesionKey, int fullmode, byte[] pInData);
|
||||
|
||||
/**
|
||||
* 用输入的会话密钥,对指定报文数据进行解密处理。
|
||||
*
|
||||
* @param srcKey 源秘钥.十六进制字符串。
|
||||
* @param desKey 目的秘钥.十六进制字符串。
|
||||
* @param sca 源算法SCA.Int类型。
|
||||
* @param sPin 源PIN块.十六进制字符串。
|
||||
* @param primaryAccount 主账号.十六进制字符串。
|
||||
* @return 目的Pin块。
|
||||
*/
|
||||
byte[] transPinFrOneKeyToAno(String srcKey, String desKey, int sca, String sPin, String primaryAccount);
|
||||
|
||||
|
||||
/**
|
||||
* 用一把DEK密钥加密数据, 报文总长度不大于8192
|
||||
*
|
||||
* @param alg 加密算法
|
||||
* @param DEK DEK密钥
|
||||
* @param infoData 数据
|
||||
* @param vector 初始向量数据 可选项,当加密模式为CBC,CFB或OFB时才显示此项
|
||||
* @param disperseAlg 分散算法
|
||||
* @return 密文数据
|
||||
*/
|
||||
byte[] SYD_Encrypt_Data(int alg, String DEK, byte[] infoData, byte[] vector, int disperseAlg, byte[] factor);
|
||||
|
||||
|
||||
/**
|
||||
* 用DEK密钥解密数据, 报文总长度不大于8192
|
||||
*
|
||||
* @param alg 解密算法
|
||||
* @param DEK DEK密钥
|
||||
* @param infoData 数据密文
|
||||
* @param vector 初始向量数据 可选项,当加密模式为CBC,CFB或OFB时才显示此项
|
||||
* @param disperseAlg 分散算法
|
||||
* @return 解密后的明文数据
|
||||
*/
|
||||
byte[] SYD_Decrypt_Data(int alg, String DEK, byte[] infoData, byte[] vector, int disperseAlg, byte[] factor);
|
||||
|
||||
|
||||
/**
|
||||
* 对于给定的数据生成一个MAC
|
||||
*
|
||||
* @param key LMK对(16-17)下加密的TAK
|
||||
* @param infoData 生成MAC的数据
|
||||
* @param IV
|
||||
* @param disperseNum 指定对根密钥分散的次数(1-3次)
|
||||
* @param disperseAlg 分散算法
|
||||
* @return 所计算出的MAC
|
||||
*/
|
||||
byte[] SYD_MAC_Data(String key, String infoData, byte[] factor, String IV, int disperseNum, int disperseAlg);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
import com.sunyard.RetWrap;
|
||||
|
||||
|
||||
/**
|
||||
* 密钥生成相关接口
|
||||
*/
|
||||
public interface SydGenApi {
|
||||
/**
|
||||
* RSA、SM2 非对称密钥产生
|
||||
*
|
||||
* @return RetWrap 包含 privateKey 和 publicKey
|
||||
* privateKey LMK 加密下的私钥
|
||||
* publicKey 公钥的 DER 编码
|
||||
*/
|
||||
RetWrap SM2GenKeyPair();
|
||||
|
||||
/**
|
||||
* RSA、SM2 非对称密钥产生
|
||||
* @param keyType 算法标识 0:RSA 1:SM2
|
||||
* @param index 27位数字,以此索引存储生成的密钥
|
||||
* @param length 长度
|
||||
* @return RetWrap 包含 privateKey 和 publicKey
|
||||
* privateKey LMK 加密下的私钥
|
||||
* publicKey 公钥的 DER 编码
|
||||
* 再之前的接口上添加了索引参数
|
||||
*/
|
||||
RetWrap SM2OrRSAGenKeyPair(int keyType,String index,int length);
|
||||
|
||||
|
||||
/**
|
||||
* 对称密钥产生
|
||||
* @param keyType 密钥类型
|
||||
* @param solution 密钥方案(LMK) 密钥长度/LMK下加密密钥的方案。
|
||||
* @return RetWrap 包含
|
||||
* lmkKey LMK LMK加密密钥
|
||||
* keyCheck 密钥校验值
|
||||
*
|
||||
*/
|
||||
RetWrap genSymmetricKey(String keyType,char solution);
|
||||
RetWrap genAndPrintSplit(String keyType,char solution);
|
||||
|
||||
|
||||
public RetWrap outputKey(String keyType, char solution, String zmk, String key);
|
||||
public RetWrap inputKey(String keyType, char solution, String zmk, String key);
|
||||
|
||||
/**
|
||||
* 密钥合成
|
||||
* @param keyType 密钥类型
|
||||
* @param keySolution 密钥方案(LMK) 密钥长度/LMK下加密密钥的方案。
|
||||
* @param keyClearPattern 两个明文分量异或合成
|
||||
* @return RetWrap 包含
|
||||
* lmkKey LMK LMK加密密钥
|
||||
* keyCheck 密钥校验值
|
||||
*
|
||||
*/
|
||||
RetWrap genComposeKey(String keyType,char keySolution,String keyClearPattern);
|
||||
RetWrap genComposeKey(String[] keys);
|
||||
/**
|
||||
* SM2 非对称密钥产生和存储
|
||||
*
|
||||
* @return RetWrap 包含 privateKey 和 publicKey
|
||||
* privateKey LMK 加密下的私钥
|
||||
* publicKey 公钥的 DER 编码
|
||||
*/
|
||||
RetWrap SYD_SM2GenKeyPair();
|
||||
|
||||
|
||||
/**
|
||||
* 此函数用于会话密钥的产生,用发起端。
|
||||
* 加密机产生随机会话密钥,输出两类密文:
|
||||
* 1、 公钥加密的密文,用于密钥的传递。
|
||||
* 2、 本地 LMK 加密,用于本地应用数据的加解密。
|
||||
*
|
||||
* @param publicKey 公钥串,DER 编码,HEX 格式。
|
||||
* @return CipherKey 公钥加密的会话密钥,DER 编码,HEX 格式, SessionKey 本地LMK 加密的会话密钥,HEX 格式 , KCV 会话密钥的检验值,HEX 格式,长度为 16H
|
||||
*/
|
||||
RetWrap SM2GenSessionKey(String publicKey);
|
||||
|
||||
|
||||
/**
|
||||
* 此函数用于会话密钥的接收,用于接收端。
|
||||
* 加密机通过使用者 ID 所对应的私钥解密对方公钥加密的密文,输出本地 LMK 加密的会话密钥,用于本地应用数据的加解密。
|
||||
*
|
||||
* @param userId 使用者的 ID,最大长度为 16 位数字,右对齐。
|
||||
* @param cipherKey 公钥加密的会话密钥,DER 编码,HEX 格式
|
||||
* @return SessionKey : 本地LMK 加密的会话密钥,HEX 格式 ; KCV 会话密钥的检验值,HEX 格式,长度为 16H。
|
||||
*/
|
||||
RetWrap SM2ConfirmSessionKeyC(String userId, String cipherKey);
|
||||
/**
|
||||
* 此函数用于会话密钥的接收,用于接收端。
|
||||
* 加密机通过使用者 ID 所对应的私钥解密对方公钥加密的密文,输出本地 LMK 加密的会话密钥,用于本地应用数据的加解密。
|
||||
*
|
||||
* @param sk 私钥
|
||||
* @param cipherKey 公钥加密的会话密钥,DER 编码,HEX 格式
|
||||
* @return SessionKey : 本地LMK 加密的会话密钥,HEX 格式 ; KCV 会话密钥的检验值,HEX 格式,长度为 16H。
|
||||
*/
|
||||
RetWrap SM2ConfirmSessionKey(String sk, String cipherKey);
|
||||
|
||||
|
||||
/**
|
||||
* 产生对称密钥,通过公钥加密生成网联格式的数字信封。
|
||||
|
||||
* @param certSerial 对*方 X509 证书的序列号。
|
||||
* @param nAlg 算法标识,0:AES,1:SM4
|
||||
* @return RetWrap 包含 CipherKey SessionKey KCV
|
||||
* CipherKey 公钥加密的会话密钥 ,BASE64 编码
|
||||
* SessionKey 本地LMK 加密的会话密钥,HEX 格式, 本地 LMK 加密的会话密钥长度,HEX 格式(不包括第 1 个字符),一般为 33 个 Bytes。默认输入值为缓冲区的大小。
|
||||
* KCV 会话密钥的检验值,HEX 格式,长度为 32H。
|
||||
*/
|
||||
RetWrap generateDE(
|
||||
String certSerial,
|
||||
byte nAlg
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 接收用私钥解密数字信封,还原对称密钥。
|
||||
*
|
||||
* @param pCertSerial 输入。 对方 X509 证书的序列号。
|
||||
* @param pCipherKey 输入。 公钥加密的会话密钥,BASE64 编码
|
||||
* @return RetWrap 包含 SessionKey KCV
|
||||
* SessionKey 输出。 本地LMK 加密的会话密钥,格式为:密钥类型|密钥密文,比如:02|密钥密文
|
||||
* KCV 会话密钥的检验值,HEX 格式,长度为 36H。
|
||||
*/
|
||||
RetWrap decryptDE(
|
||||
String pCertSerial,
|
||||
String pCipherKey
|
||||
);
|
||||
|
||||
/**
|
||||
* 产生要求长度的随即数据串,可用于身份认证
|
||||
*
|
||||
* @param nRandomSize 需要输出的随机串的长度
|
||||
* @return 未抛出异常表示成功, 返回 HEX 格式的密钥
|
||||
*
|
||||
*/
|
||||
String GenerateRandom(
|
||||
int nRandomSize
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
|
||||
/**
|
||||
* 密钥工具类接口
|
||||
* 不影响数据库中的密钥
|
||||
*/
|
||||
public interface SydPINOpt {
|
||||
|
||||
|
||||
String transPINFromZPKToZPK(String zpk1, String zpk2, int sca, int dca, int spt, int dpt, String pin, String account);
|
||||
|
||||
String transPINFromTPKToZPK(String tpk, String zpk, int sca, int dca, int spt, int dpt, String pin, String account);
|
||||
|
||||
//
|
||||
// /**
|
||||
// * 将 PIN 从一个 ZPK 加密转为另一个 ZPK 加密
|
||||
// * @param zpk1 源 PIN保护密钥
|
||||
// * @param zpk2 目标 PIN保护密钥
|
||||
// * @param account1 源账号
|
||||
// * @param account2 目标账号
|
||||
// * @param pin 源 PIN 密文
|
||||
// * @return PIN 密文
|
||||
// */
|
||||
// String transPinFromZPKToZPK(String zpk1, String zpk2, String account1, String account2, String pin);
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 将 PIN 从一个 ZPK 加密转为另一个 ZPK 加密
|
||||
// * @param zpk1 源 PIN保护密钥
|
||||
// * @param zpk2 目标 PIN保护密钥
|
||||
// * @param account 账号
|
||||
// * @param pin 源 PIN 密文
|
||||
// * @return PIN 密文
|
||||
// */
|
||||
// String transPinFromTPKToZPK(String zpk1, String zpk2, String account, String pin);
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// *
|
||||
// * ZPK转PVK加密的IBM PIN OFFSET
|
||||
// *
|
||||
// * @param zpk 区域 PIN保护密钥
|
||||
// * @param pvk 验 PIN 专用密钥
|
||||
// * @param account1 源账号
|
||||
// * @param account2 目标账号
|
||||
// * @param pin ZPK 加密的 PIN 密文
|
||||
// * @return IBM PIN OFFSE
|
||||
// */
|
||||
// String calculateIBMPinOffsetFromZPKToPVK(String zpk, String pvk, String account1, String account2, String pin);
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * ZPK转PVK加密的IBM PIN OFFSET并校验
|
||||
// *
|
||||
// * @param zpk 区域 PIN保护密钥
|
||||
// * @param pvk 验 PIN 专用密钥
|
||||
// * @param account1 源账号
|
||||
// * @param account2 目标账号
|
||||
// * @param pin ZPK 加密的 PIN 密文
|
||||
// * @param pinOffset IBM PIN OFFSE
|
||||
// * @return true 校验通过 / false 校验不通过
|
||||
// */
|
||||
// Boolean verifyIBMPinOffsetFromZPKToPVK(String zpk, String pvk, String account1, String account2, String pin, String pinOffset);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
public interface SydPledge {
|
||||
|
||||
/**
|
||||
* 编押
|
||||
* @param AreaCode 地区代码 6 位
|
||||
* @param Alg SydApi.NALG_3DES/SydApi.NALG_SM4
|
||||
* @param Version 版本号
|
||||
* @param Data 原始数据
|
||||
* @return MAC 长度为 8 的 HEX字符串
|
||||
*/
|
||||
public String GenerateMIYA(String AreaCode, int Version, int Alg, byte[] Data);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param AreaCode 地区代码 6 位
|
||||
* @param Alg SydApi.NALG_3DES/SydApi.NALG_SM4
|
||||
* @param Version 版本号
|
||||
* @param MAC 长度为 8 的 HEX字符串
|
||||
* @param Data 原始数据
|
||||
* @return true=核押通过 false=核押不通过
|
||||
*/
|
||||
public boolean VerifyMIYA(String AreaCode, int Version, int Alg, String MAC, byte[] Data);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
public interface SydRawApi {
|
||||
|
||||
/**
|
||||
* 加密机直接通信
|
||||
* @param pack 组好的 Hex 格式包
|
||||
* @return 返回加密机返回 Hex 格式包
|
||||
*/
|
||||
public String send(String pack);
|
||||
|
||||
|
||||
/**
|
||||
* 加密机直接通信
|
||||
* @param pack 组好的包
|
||||
* @return 返回加密机返回包
|
||||
*/
|
||||
public byte[] send(byte[] pack);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package com.sunyard.inf;
|
||||
|
||||
|
||||
import com.sunyard.RetWrap;
|
||||
|
||||
/**
|
||||
* 签名验签相关接口
|
||||
*/
|
||||
public interface SydSVApi extends SydNakedSVApi, SydAttachedSVApi, SydDetachedSVApi{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 不经过 CA 授信
|
||||
* 直接使用公私钥对签名验签
|
||||
*/
|
||||
interface SydNakedSVApi {
|
||||
/**
|
||||
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public byte[] SYD_NakedSign(
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
public boolean SYD_NakedVerify(
|
||||
byte[] orgData,
|
||||
byte[] sign,
|
||||
String sCertDN
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 带原文的签名验签
|
||||
*/
|
||||
interface SydAttachedSVApi {
|
||||
|
||||
/**
|
||||
* SM2 私钥签名
|
||||
* @param pUserID 使用者的 ID,最大长度为 16 位数字,右对齐。
|
||||
* @param certNo 证书号
|
||||
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据
|
||||
* @param publicKey 公钥的 DER 编码
|
||||
* @param orgData 原始数据
|
||||
* @return 签名的 base64 编码
|
||||
*/
|
||||
String SM2SignC(
|
||||
String pUserID,
|
||||
String certNo,
|
||||
int nOrgDataType,
|
||||
byte[] publicKey,
|
||||
byte[] orgData
|
||||
);
|
||||
|
||||
/**
|
||||
* RSA 私钥签名
|
||||
* @param HashMark 哈希标识 指示用于哈希证书数据的哈希算法的标识。0: SHA1 1: SHA256 2: MD5。
|
||||
* @param privateKeyTag 私钥标记 指示私钥位置的标记。数字为存储私钥的索引,除了全9表示使用由命令中提供的密钥。
|
||||
* 27位的索引号:16位机构号+3位密钥类型+8位密钥索引号
|
||||
* @param nOrgDataType 原始数据类型 0 : hash 1 : 原数据
|
||||
* @param orgData 原始数据
|
||||
* @return 签名的 base64 编码
|
||||
*/
|
||||
byte[] RSASignC(
|
||||
String privateKeyTag,
|
||||
int HashMark,
|
||||
int nOrgDataType,
|
||||
byte[] orgData);
|
||||
|
||||
|
||||
byte[] RSASign(
|
||||
String privateKey,
|
||||
int HashMark,
|
||||
int nOrgDataType,
|
||||
byte[] orgData);
|
||||
|
||||
/**
|
||||
* 采用 RSA 算法,用指定的公钥对指定的原始数据进行数字签名验证。
|
||||
* @param HashMark 证书号
|
||||
* @param nOrgDataType 签名方式
|
||||
* @param publicKey 公钥
|
||||
* @param orgData 原始数据
|
||||
* @param sign base64 格式的签名
|
||||
* @return true 验签通过 false 验签失败
|
||||
*/
|
||||
boolean RSAVerify(
|
||||
int HashMark,
|
||||
int nOrgDataType,
|
||||
byte[] publicKey,
|
||||
byte[] orgData,
|
||||
byte[] sign);
|
||||
|
||||
|
||||
/**
|
||||
* 采用 SM2 算法,用指定的公钥对指定的原始数据进行数字签名验证。
|
||||
* @param certNo 哈希标识 指示用于哈希证书数据的哈希算法的标识。0: SHA1 1: SHA256 2: MD5
|
||||
* @param nOrgDataType 签名方式
|
||||
* @param publicKey 公钥
|
||||
* @param orgData 原始数据
|
||||
* @param sign base64 格式的签名
|
||||
* @return true 验签通过 false 验签失败
|
||||
*/
|
||||
boolean SM2Verify(
|
||||
String certNo,
|
||||
int nOrgDataType,
|
||||
byte[] publicKey,
|
||||
byte[] orgData,
|
||||
String sign
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* SM2 私钥签名
|
||||
* @param certNo 证书号
|
||||
* @param orgData 原始数据
|
||||
* @return 签名的 base64 编码
|
||||
*/
|
||||
String SM2SignCustomized(
|
||||
String certNo,
|
||||
byte[] orgData
|
||||
);
|
||||
|
||||
/**
|
||||
* 采用 SM2 算法,用指定的公钥对指定的原始数据进行数字签名验证。
|
||||
* @param certNo 证书号
|
||||
* @param orgData 原始数据
|
||||
* @param sign base64 格式的签名
|
||||
* @return true 验签通过 false 验签失败
|
||||
*/
|
||||
boolean SM2VerifyCustomized(
|
||||
String certNo,
|
||||
byte[] orgData,
|
||||
String sign
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 不带原文的签名验签
|
||||
*/
|
||||
interface SydDetachedSVApi {
|
||||
|
||||
/**
|
||||
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
public boolean SYD_DetachedVerify(
|
||||
byte[] orgData,
|
||||
String sign);
|
||||
|
||||
|
||||
/**
|
||||
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public String SYD_DetachedSign(
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
|
||||
* 待签名的原始数据将在接口内部进行 sm3 ,然后做 Detach 签名
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param publicKey sm3 hash 所用的公钥
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public String sm3AndDetachedSign(
|
||||
byte[] orgData,
|
||||
String publicKey,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
|
||||
* 原始数据将在接口内部进行 sm3 ,然后做 Detach 验签
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param publicKey sm3 hash 所用的公钥
|
||||
* @param sign 签名数据
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
public boolean sm3AndDetachedVerify(
|
||||
byte[] orgData,
|
||||
String publicKey,
|
||||
String sign);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
|
||||
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
|
||||
*
|
||||
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
|
||||
* @param orgData 输入的数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public String detachedSign(
|
||||
int dataType,
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
//8024
|
||||
public byte[] detachedSign(
|
||||
int dataType,
|
||||
byte[] orgData,
|
||||
int sCertDN
|
||||
);
|
||||
|
||||
public String detachedSignbysn(
|
||||
int dataType,
|
||||
byte[] orgData,
|
||||
String certificateNo);
|
||||
|
||||
|
||||
/**
|
||||
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
|
||||
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
|
||||
*
|
||||
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
boolean detachedVerify(
|
||||
int dataType,
|
||||
byte[] orgData,
|
||||
String sign);
|
||||
//8025
|
||||
boolean detachedVerify(
|
||||
int dataType,
|
||||
byte[] orgData,
|
||||
byte[] sign);
|
||||
|
||||
RetWrap SM3Hash(int packSn, String userId, byte[] publicKey, byte[] msg, byte[] filterData);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.sunyard.inf.customize;
|
||||
|
||||
import com.sunyard.cert.X509;
|
||||
|
||||
public interface SydHAApi {
|
||||
|
||||
/**
|
||||
* 通过机构实体ID获得使用者的SM2公钥(DER编码)
|
||||
* @param pUserID 本机构实体ID,最大长度为16位数字,即设备安装生成实体时的实体机构输入栏的内容
|
||||
* @param nKeyType 密钥类型,0:签名公钥,1:加密公钥,如无加解密业务,传入0即可
|
||||
* @return 输出的公钥串,DER编码,HEX格式,此公钥是机构自己公钥证书的公钥
|
||||
*/
|
||||
public String SYD_SM2_Get_Id_PublicKey_HA (
|
||||
String pUserID,
|
||||
int nKeyType
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 通过证书DN获得机构的公钥(DER编码),联调前需要导入公钥证书
|
||||
* @param Dn 证书的DN,每个证书有唯一的DN
|
||||
* @param nKeyType 密钥类型,0:签名公钥,1:加密公钥,如无加解密业务,传入0即可
|
||||
* @return 输出的公钥串,DER编码,HEX格式,此公钥为他方机构的公钥
|
||||
*/
|
||||
public String SYD_SM2_Get_Dn_PublicKey_HA (
|
||||
byte[] Dn,
|
||||
int nKeyType
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 通过本机构实体ID所对应的私钥对指定的原始数据进行数字签名(PKCS#1)
|
||||
* @param pUserID 本机构实体ID,最大长度为16位数字,即设备安装生成实体时的实体机构输入栏的内容
|
||||
* @param nOrgDataType 输入的数据类型,0:HASH值,1:原始数据,原始数据由加密设备内部完成HASH并签名
|
||||
* @param publicKey 公钥串,DER编码,HEX格式。仅 OrgDataType=1有效, 2.1章节接口,输出公钥原串传入
|
||||
* @param orgData 待签名的原始数据
|
||||
* @return 签名数据( DER 编码 + Base64 编码)
|
||||
*/
|
||||
public String SYD_SM2_Sign_HA(
|
||||
String pUserID,
|
||||
int nOrgDataType,
|
||||
byte[] publicKey,
|
||||
byte[] orgData
|
||||
);
|
||||
|
||||
/**
|
||||
* 通过本机构实体ID所对应的私钥对指定的原始数据进行数字签名(PKCS#1)
|
||||
* @param nOrgDataType 输入的数据类型,0:HASH值,1:原始数据,原始数据由加密设备内部完成HASH并签名
|
||||
* @param privateKey 私钥串,LMK34-35 下加密的私钥
|
||||
* @param publicKey 公钥串,DER编码,HEX格式。仅 OrgDataType=1有效, 2.1章节接口,输出公钥原串传入
|
||||
* @param orgData 待签名的原始数据
|
||||
* @return 签名数据( DER 编码 + Base64 编码)
|
||||
*/
|
||||
public String SYD_SM2_Sign_HA(
|
||||
int nOrgDataType,
|
||||
byte[] privateKey,
|
||||
byte[] publicKey,
|
||||
byte[] orgData
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用指定的公钥对指定的原始数据进行数字签名验证(PKCS#1)
|
||||
* @param nOrgDataType 数据类型,SydApi.DATA_ORIGIN 原始数据 SydApi.DATA_HASH : hash 后的类型
|
||||
* @param publicKey 公钥串,DER编码,HEX格式,2.1章节接口,输出公钥原串传入
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据 (DER 编码 + Base64 编码)
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
public boolean SYD_SM2_Verify_HA(
|
||||
int nOrgDataType,
|
||||
byte[] publicKey,
|
||||
byte[] orgData,
|
||||
String sign
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
public boolean SYD_SM2_DetachedVerify_HA(
|
||||
byte[] orgData,
|
||||
String sign );
|
||||
|
||||
|
||||
/**
|
||||
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public String SYD_SM2_DetachedSign_HA(
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 外部私钥
|
||||
public String SM2Sign(
|
||||
int nOrgDataType,
|
||||
byte[] privateKey,
|
||||
byte[] orgData
|
||||
);
|
||||
|
||||
// SYD_SM2_Verify_HA
|
||||
public boolean SM2Verify(
|
||||
int nOrgDataType,
|
||||
byte[] publicKey,
|
||||
byte[] orgData,
|
||||
String base64Sign
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.sunyard.inf.customize;
|
||||
|
||||
|
||||
/**
|
||||
* 网联全称 "网联清算有限公司"(China Nets Union Clearing Corporation)
|
||||
* 是一个线上支付统一清算平台(unified clearing platform for online payment),在央行指导下,由中国支付清算协会(Payment & Clearing Association of China)组织支付机构成立,用以处理由非银行支付机构发起的、与银行交互的支付业务。
|
||||
*/
|
||||
public interface SydQNUCApi {
|
||||
|
||||
|
||||
/**
|
||||
* 用指定的证书私钥对指定的数据进行数字签名。
|
||||
* @param pCertSerial 输入。签名 X509 证书的序列号。
|
||||
* @param pOrgData 输入。 待签名的原始数据。
|
||||
* @return 签名数据(BASE64 编码)。
|
||||
*/
|
||||
public String netSign(String pCertSerial, byte[] pOrgData);
|
||||
|
||||
|
||||
/**
|
||||
* 用指定证书对指定的原始数据进行数字签名验证。
|
||||
* @param pCertSerial 输入。 签名 X509 证书的序列号。
|
||||
* @param pOrgData 输入。 待签名的原始数据。
|
||||
* @param pSignData 输入。 签名数据(BASE64 编码)。
|
||||
* @return true 表示验证正确;false 表示失败;
|
||||
*/
|
||||
boolean netVerify(
|
||||
String pCertSerial,
|
||||
byte[] pOrgData,
|
||||
String pSignData
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.sunyard.inf.customize;
|
||||
|
||||
import com.sunyard.cert.X509;
|
||||
|
||||
/**
|
||||
* 山东农信定制开发接口
|
||||
*/
|
||||
public interface SydSDNXApi {
|
||||
|
||||
/**
|
||||
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public String nakedSign(
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* 使用指定的证书机构号,对指定的原始数据编制裸验签(遵循PKCS#1)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @param organizationNum 机构号
|
||||
* @return 验签结果,true:表示验证正确;验签不通过返回错误码和错误信息
|
||||
*/
|
||||
public boolean SYD_NakedVerify(
|
||||
byte[] orgData,
|
||||
String sign,
|
||||
String organizationNum
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 验签,通过传入行号字符串,获取证书去验签
|
||||
* @param bNumber 行号,通过行号获取证书
|
||||
* @param orgData 带签名的原始数据
|
||||
* @param signData 签名数据( BASE64 编码)
|
||||
* @return 验签结果,true:表示验证正确;验签不通过返回错误码和错误信息
|
||||
*/
|
||||
/* boolean netVerify(
|
||||
String bNumber,
|
||||
byte[] orgData,
|
||||
String signData
|
||||
);
|
||||
*/
|
||||
/**
|
||||
*验签 ,上传并返回证书内容,并更新机构号
|
||||
* @param bNumber 行号,通过行号获取证书
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据( BASE64 编码)
|
||||
* @return 证书信息(包含公钥字段)
|
||||
*/
|
||||
public X509 SYD_Get_X509_CertInfo_HA(
|
||||
String bNumber,
|
||||
byte[] orgData,
|
||||
String sign
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.sunyard.inf.customize;
|
||||
|
||||
import com.sunyard.SydApiException;
|
||||
import com.sunyard.cert.X509;
|
||||
import com.sunyard.proto.Packet;
|
||||
import com.sunyard.proto.PacketSection;
|
||||
import com.sunyard.proto.Util;
|
||||
import com.sunyard.trans.PacketSN;
|
||||
import racal.sunyard.main.SydApi4j;
|
||||
import racal.sunyard.main.proto.Proto8003;
|
||||
import racal.sunyard.main.proto.Proto8004;
|
||||
import racal.sunyard.main.proto.Proto8012;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SydSDNXApiImpl extends SydApi4j implements SydSDNXApi {
|
||||
|
||||
|
||||
public String nakedSign(byte[] orgData, String sCertDN) {
|
||||
Proto8003 proto = new Proto8003(); //pset.getProtocolReqRender("75");
|
||||
byte[] dn = new byte[256];
|
||||
byte[] s = null;
|
||||
try {
|
||||
s = sCertDN.getBytes("GBK");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.arraycopy(s, 0, dn, 0, s.length);
|
||||
|
||||
// 填充数据
|
||||
HashMap<String, Object> packet = new HashMap<String, Object>();
|
||||
HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
packet.put("data", data);
|
||||
PacketSN sn = PacketSN.gen();
|
||||
packet.put("header", sn.getSn().array());
|
||||
data.put("signatureDataType$option", 1);
|
||||
data.put("DN", dn);
|
||||
data.put("data", orgData);
|
||||
// 渲染发送
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
return Util.encodeBase64(((PacketSection) ret.get("signature")).getBytes());
|
||||
//return ((PacketSection) ret.get("signature")).getBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean SYD_NakedVerify(byte[] orgData, String sign, String organizationNum) {
|
||||
Proto8004 proto = new Proto8004(); //pset.getProtocolReqRender("75");
|
||||
|
||||
byte[] dn = new byte[256];
|
||||
byte[] s = null;
|
||||
|
||||
|
||||
// 填充数据
|
||||
HashMap<String, Object> packet = new HashMap<String, Object>();
|
||||
HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
packet.put("data", data);
|
||||
PacketSN sn = PacketSN.gen();
|
||||
packet.put("header", sn.getSn().array());
|
||||
data.put("signatureDataType$option", 2);
|
||||
data.put("organizationNum", organizationNum);
|
||||
data.put("data", orgData);
|
||||
data.put("signature", Util.decodeBase64(sign));
|
||||
data.put("returnSign$option", 0);
|
||||
// 渲染发送
|
||||
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 true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509 SYD_Get_X509_CertInfo_HA(String bNumber, byte[] orgData, String sign) {
|
||||
|
||||
Proto8012 proto = new Proto8012(); //pset.getProtocolReqRender("75");
|
||||
|
||||
|
||||
// 填充数据
|
||||
HashMap<String, Object> packet = new HashMap<String, Object>();
|
||||
HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
packet.put("data", data);
|
||||
PacketSN sn = PacketSN.gen();
|
||||
packet.put("header", sn.getSn().array());
|
||||
data.put("originData", orgData);
|
||||
data.put("signData", sign.getBytes());
|
||||
data.put("flag$option", 2);
|
||||
data.put("organizationNum", bNumber);
|
||||
// 渲染发送
|
||||
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());
|
||||
}
|
||||
|
||||
PacketSection info = (PacketSection) ret.get("info");
|
||||
|
||||
byte[] pCertInfo = info.getBytes();
|
||||
// X509 cinfo = new X509();
|
||||
// cinfo.setIssuer(Util.toCleanString(pCertInfo, 0, 257));
|
||||
// cinfo.setSerialNumber(Util.toCleanString(pCertInfo, 257, 65));
|
||||
// cinfo.setSubject(Util.toCleanString(pCertInfo, 257 + 65, 257));
|
||||
// cinfo.setNotBefore(Util.toCleanString(pCertInfo, 257 + 65 + 257, 15));
|
||||
// cinfo.setNotAfter(Util.toCleanString(pCertInfo, 257 + 65 + 257 + 15, 15));
|
||||
// byte[] blen = new byte[]{pCertInfo[257 + 65 + 257 + 15 + 15], pCertInfo[257 + 65 + 257 + 15 + 16]};
|
||||
// int len = Util.b2i(blen);
|
||||
// byte[] pem = new byte[len];
|
||||
// System.arraycopy(pCertInfo, 257 + 65 + 257 + 15 + 17, pem, 0, len);
|
||||
// String pp = new String(pem);
|
||||
// 解析证书
|
||||
return GetX509CertInfo(new String(pCertInfo));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum AlgorithmType {
|
||||
|
||||
// DES 加密
|
||||
ENCRYPT_DES,
|
||||
// DES 解密
|
||||
DECRYPT_DES,
|
||||
// AES 加密
|
||||
ENCRYPT_AES,
|
||||
// AES 解密
|
||||
DECRYPT_AES,
|
||||
// SSF33 加密
|
||||
ENCRYPT_SSF33,
|
||||
// SSF33 解密
|
||||
DECRYPT_SSF33,
|
||||
// SM1 加密
|
||||
ENCRYPT_SM1,
|
||||
// SM1 解密
|
||||
DECRYPT_SM1,
|
||||
// SM4 加密
|
||||
ENCRYPT_SM4,
|
||||
// SM4 解密
|
||||
DECRYPT_SM4,
|
||||
// IDEA 加密
|
||||
ENCRYPT_IDEA,
|
||||
// IDEA 解密
|
||||
DECRYPT_IDEA,
|
||||
// AES256 加密
|
||||
ENCRYPT_AES256,
|
||||
// AES256 解密
|
||||
DECRYPT_AES256,
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public enum CMD {
|
||||
|
||||
// 加解密
|
||||
ENCRYPTION_DECRYPTION("E0");
|
||||
|
||||
private String value;
|
||||
|
||||
public ByteBuffer getValue() {
|
||||
return ByteBuffer.wrap(value.getBytes());
|
||||
}
|
||||
|
||||
CMD(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum DataType {
|
||||
|
||||
// 二进制
|
||||
BIN,
|
||||
// 十六进制编码的二进制
|
||||
HEX,
|
||||
// 文本格式
|
||||
TXT
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum FullEndType {
|
||||
|
||||
/**
|
||||
* 填充数据的最后一个字节不填充计数位。解
|
||||
密后的数据包含填充数据,由应用摘取实际数据。
|
||||
*/
|
||||
WITH_END,
|
||||
/**
|
||||
* 填充数据的最后一个字节填充计数位。计数
|
||||
位取值在 0x01 to 0x08/ 0x10 之间。解密后
|
||||
的数据由加密机根据 Pad count flag 值在内部自
|
||||
动去掉填充数据
|
||||
*/
|
||||
AUTO_END,
|
||||
|
||||
/**
|
||||
* pkcs5和 pkcs7 填充
|
||||
*/
|
||||
PKCS5_PKCS7
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
/**
|
||||
*/
|
||||
public enum FullMode {
|
||||
|
||||
/**
|
||||
* 如果数据块长度为 8/16 的整数倍,不需要填
|
||||
充;如果长度不为 8/16 的整数倍,填充至长度满
|
||||
8/16 的整数倍(填充方式按 Pad character 域中
|
||||
描述的规则进行,由加密机内部自动完成)
|
||||
*/
|
||||
FULL_8_16,
|
||||
/**
|
||||
* 如果数据块长度为 8/16 的整数倍,填充一个
|
||||
整 8/16 字节的数据(填充方式按 Pad character
|
||||
域中描述的规则进行,由加密机内部自动完成);
|
||||
如果长度不为8/16的整数倍,填充至长度满8/16
|
||||
的整数倍(填充方式按 Pad character 域中描述
|
||||
的规则进行,由加密机内部自动完成)
|
||||
*/
|
||||
FULL_MORE_8_16
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum KeyType {
|
||||
|
||||
// LMK 加密的 ZEK (区域加密密钥)
|
||||
ZEK,
|
||||
// LMK 加密的 TEK ()
|
||||
TEK,
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum PackType {
|
||||
|
||||
// 唯一块
|
||||
ONLY,
|
||||
// 起始块
|
||||
HEAD,
|
||||
// 中间块
|
||||
MIDDLE,
|
||||
// 结束块
|
||||
TAIL
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
import com.sunyard.proto.Util;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* 生成包序号,不负责销毁。
|
||||
* 相同设备 sn 轮转
|
||||
* 不同设备 sn 无关
|
||||
*/
|
||||
public class PacketSN {
|
||||
|
||||
private static HashMap<String, SN> keeper = new HashMap<String, SN>();
|
||||
|
||||
private ByteBuffer sn;
|
||||
private String devid;
|
||||
|
||||
public static PacketSN gen(String devid){
|
||||
|
||||
// 申请小锁
|
||||
SN sn = keeper.get(devid);
|
||||
if ( null == sn){
|
||||
// 申请全局锁
|
||||
synchronized (PacketSN.class){
|
||||
SN snCheck = keeper.get(devid);
|
||||
if( null == snCheck){
|
||||
keeper.put(devid, new SN());
|
||||
sn = keeper.get(devid);
|
||||
}else{
|
||||
sn = snCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new PacketSN(sn.next(), devid);
|
||||
}
|
||||
|
||||
public static PacketSN gen(){
|
||||
return gen("default");
|
||||
}
|
||||
|
||||
public PacketSN(ByteBuffer sn, String devid) {
|
||||
this.sn = sn;
|
||||
this.devid = devid;
|
||||
}
|
||||
|
||||
public ByteBuffer getSn() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public String getDevid() {
|
||||
return devid;
|
||||
}
|
||||
|
||||
public String getGlobalId(){
|
||||
return devid + "-" + Util.bytes2HexString(sn.array());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SN {
|
||||
private long sn = 0;
|
||||
|
||||
synchronized ByteBuffer next(){
|
||||
ByteBuffer bb = ByteBuffer.allocate(8);
|
||||
bb.put((byte) ((sn >>> 56) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 48) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 40) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 32) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 24) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 16) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 8) & 0xFF));
|
||||
bb.put((byte) (sn & 0xFF));
|
||||
sn += 1;
|
||||
return bb;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
|
||||
public enum RoundType {
|
||||
|
||||
// 占位
|
||||
DO_NOT_USE,
|
||||
// 电子密码本
|
||||
ECB,
|
||||
// 密码块连接
|
||||
CBC,
|
||||
// 分组长度密码反馈
|
||||
CFB,
|
||||
// 分组长度输出反馈
|
||||
OFB
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
package com.sunyard.trans.pkg;
|
||||
|
||||
import com.sunyard.trans.FullMode;
|
||||
import com.sunyard.SydApiException;
|
||||
import com.sunyard.proto.Util;
|
||||
import com.sunyard.trans.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class DataEncryptDecryptPacket extends Packet {
|
||||
|
||||
// 包类型
|
||||
private int packType;
|
||||
// 算法标记
|
||||
private int alg;
|
||||
// 轮类型
|
||||
private int round;
|
||||
// 密钥类型
|
||||
private int keyType;
|
||||
// 密钥
|
||||
private byte[] key;
|
||||
// 输入数据类型
|
||||
private int inDataType;
|
||||
// 输出数据类型
|
||||
private int outDataType;
|
||||
// 填充模式
|
||||
private int fullMode;
|
||||
// 填充字符
|
||||
private String fullCharacter;
|
||||
// 填充类型
|
||||
private int fullEndType;
|
||||
/**
|
||||
* 消息类型影响消息长度(若消息类型为二进制,则为
|
||||
* 随后域长度;若消息类型为扩展十六进制,则为随后
|
||||
* 域长度的一半)。默认是 BIN
|
||||
*/
|
||||
private int messageType;
|
||||
|
||||
// 消息数据
|
||||
private byte[] message;
|
||||
|
||||
|
||||
public DataEncryptDecryptPacket() {
|
||||
this.setCommand(CMD.ENCRYPTION_DECRYPTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataEncryptDecryptPacket clone(){
|
||||
DataEncryptDecryptPacket subPack = new DataEncryptDecryptPacket();
|
||||
subPack.setCommand(getCommand());
|
||||
subPack.setHeader(getHeader());
|
||||
subPack.setPackType(packType);
|
||||
subPack.setAlg(alg);
|
||||
subPack.setRound(round);
|
||||
subPack.setKeyType(keyType);
|
||||
subPack.setKey(key);
|
||||
subPack.setInDataType(inDataType);
|
||||
subPack.setOutDataType(outDataType);
|
||||
subPack.setFullMode(fullMode);
|
||||
subPack.setFullCharacter(fullCharacter);
|
||||
subPack.setFullEndType(fullEndType);
|
||||
return subPack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始向量
|
||||
* 仅当密钥加密轮函数类型为 CBC ,CFB ,OFB 时有此域。
|
||||
* 当密钥模式为 DES加解密 该域为 16H
|
||||
* 当密钥模式为 AES SSF33 SM1 加解密时,该域为 32H
|
||||
*/
|
||||
private byte[] iv = new byte[0];
|
||||
|
||||
|
||||
public void setKeyType(KeyType keyType) {
|
||||
this.keyType = keyType.ordinal();
|
||||
}
|
||||
|
||||
|
||||
public void setRoundType(RoundType roundType) {
|
||||
this.round = roundType.ordinal();
|
||||
}
|
||||
|
||||
public void setPackType(PackType type) {
|
||||
this.packType = type.ordinal();
|
||||
}
|
||||
|
||||
public void setAlgType(AlgorithmType type){
|
||||
this.alg = type.ordinal();
|
||||
}
|
||||
|
||||
public void setKey(byte[] key){
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
||||
public void setIv(byte[] iv) {
|
||||
if ( RoundType.CBC.ordinal() == round
|
||||
|| RoundType.CFB.ordinal() == round
|
||||
|| RoundType.OFB.ordinal() == round
|
||||
){
|
||||
if( AlgorithmType.ENCRYPT_DES.ordinal() == keyType
|
||||
|| AlgorithmType.DECRYPT_DES.ordinal() == keyType
|
||||
){
|
||||
if( 16 != iv.length ){
|
||||
throw new SydApiException(65535);
|
||||
}
|
||||
}else{
|
||||
if( 32 != iv.length ){
|
||||
throw new SydApiException(65535);
|
||||
}
|
||||
}
|
||||
this.iv = iv;
|
||||
}
|
||||
throw new SydApiException(65535);
|
||||
|
||||
}
|
||||
|
||||
public void setInDataType(DataType dataType) {
|
||||
this.inDataType = dataType.ordinal();
|
||||
}
|
||||
|
||||
public void setOutDataType(DataType dataType) {
|
||||
this.outDataType = dataType.ordinal();
|
||||
}
|
||||
|
||||
public void setFullMode(FullMode mode,FullEndType endType, String firstChar, String otherChar){
|
||||
this.fullMode = mode.ordinal();
|
||||
this.fullCharacter = firstChar + otherChar;
|
||||
this.fullEndType = endType.ordinal();
|
||||
}
|
||||
|
||||
public void setMessage(DataType type , byte[] message) {
|
||||
this.message = message;
|
||||
this.messageType = type.ordinal();
|
||||
}
|
||||
|
||||
public void setMessage(byte[] message) {
|
||||
setMessage(DataType.BIN, message);
|
||||
}
|
||||
|
||||
private ByteBuffer toSubPack(){
|
||||
ByteBuffer bb = ByteBuffer.allocate(MAX_PACKAGE_DATA_LEN);
|
||||
bb.put( Util.int2charbyte16(packType) );
|
||||
bb.put( Util.int2charbyte16(alg) );
|
||||
bb.put( Util.int2charbyte16(round) );
|
||||
bb.put( Util.int2charbyte16(keyType));
|
||||
bb.put( key );
|
||||
bb.put( Util.int2charbyte16(inDataType) );
|
||||
bb.put( Util.int2charbyte16(outDataType) );
|
||||
if ( 0 == packType || 3 == packType ){
|
||||
bb.put( Util.int2charbyte16(fullMode) );
|
||||
bb.put( fullCharacter.getBytes() );
|
||||
bb.put( Util.int2charbyte16(fullEndType));
|
||||
}
|
||||
bb.put(iv);
|
||||
int msgLen = message.length;
|
||||
if ( DataType.HEX.ordinal() == messageType ){
|
||||
msgLen = msgLen/2;
|
||||
}
|
||||
bb.put(String.format("%03X", msgLen).getBytes());
|
||||
bb.put(message);
|
||||
|
||||
this.setData(bb);
|
||||
|
||||
return this.pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer toSendPack(PacketSN sn) {
|
||||
|
||||
setHeader(sn.getSn());
|
||||
|
||||
// 依据数据长度的不同可能需要分包
|
||||
int packLen = 2048;
|
||||
int inDataLen = this.message.length;
|
||||
// 拆包数量
|
||||
int loop = inDataLen / packLen;
|
||||
if ( 0 != inDataLen % packLen ){
|
||||
loop += 1;
|
||||
}
|
||||
|
||||
ByteBuffer bb = ByteBuffer.allocate( packLen * loop );
|
||||
|
||||
int i = 0;
|
||||
while ( i < loop){
|
||||
|
||||
DataEncryptDecryptPacket subPack = this.clone();
|
||||
if ( 0 == i){
|
||||
if ( 1 == loop){
|
||||
subPack.setPackType(PackType.ONLY);
|
||||
}else{
|
||||
subPack.setPackType(PackType.HEAD);
|
||||
}
|
||||
}else{
|
||||
if ( (loop - 1) == i){
|
||||
subPack.setPackType(PackType.TAIL);
|
||||
}else{
|
||||
subPack.setPackType(PackType.MIDDLE);
|
||||
}
|
||||
}
|
||||
|
||||
// 唯一包
|
||||
if ( 1 == loop){
|
||||
subPack.setMessage(this.message);
|
||||
}else{
|
||||
byte[] tMsg = new byte[packLen];
|
||||
// 最后一个包
|
||||
if ( (loop - 1) == i){
|
||||
System.arraycopy(this.message, i * packLen , tMsg, 0, this.message.length % packLen);
|
||||
}else{ // 其他包
|
||||
System.arraycopy(this.message, i * packLen , tMsg, 0, packLen);
|
||||
}
|
||||
subPack.setMessage(tMsg);
|
||||
}
|
||||
|
||||
bb.put( subPack.toSubPack() );
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// POJO set
|
||||
|
||||
public void setPackType(int packType) {
|
||||
this.packType = packType;
|
||||
}
|
||||
|
||||
public void setAlg(int alg) {
|
||||
this.alg = alg;
|
||||
}
|
||||
|
||||
public void setRound(int round) {
|
||||
this.round = round;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public void setInDataType(int inDataType) {
|
||||
this.inDataType = inDataType;
|
||||
}
|
||||
|
||||
public void setOutDataType(int outDataType) {
|
||||
this.outDataType = outDataType;
|
||||
}
|
||||
|
||||
public void setFullMode(int fullMode) {
|
||||
this.fullMode = fullMode;
|
||||
}
|
||||
|
||||
public void setFullCharacter(String fullCharacter) {
|
||||
this.fullCharacter = fullCharacter;
|
||||
}
|
||||
|
||||
public void setFullEndType(int fullEndType) {
|
||||
this.fullEndType = fullEndType;
|
||||
}
|
||||
|
||||
public void setMessageType(int messageType) {
|
||||
this.messageType = messageType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.sunyard.trans.pkg;
|
||||
|
||||
|
||||
import com.sunyard.trans.CMD;
|
||||
import com.sunyard.trans.PacketSN;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* SJJ1316 加密机通用格式
|
||||
*/
|
||||
public abstract class Packet {
|
||||
|
||||
public static final int MAX_PACKAGE_DATA_LEN = 8192;
|
||||
public static final int MAX_PACKAGE_LEN = MAX_PACKAGE_DATA_LEN + 10;
|
||||
|
||||
|
||||
private ByteBuffer header;
|
||||
private ByteBuffer command;
|
||||
private ByteBuffer data;
|
||||
private ByteBuffer length;
|
||||
|
||||
|
||||
|
||||
public abstract ByteBuffer toSendPack(PacketSN sn);
|
||||
|
||||
|
||||
public ByteBuffer getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public ByteBuffer getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public void setCommand(CMD cmd) {
|
||||
this.command = cmd.getValue();
|
||||
}
|
||||
|
||||
public void setCommand(ByteBuffer command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public void setHeader(ByteBuffer header){
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public void setData(ByteBuffer data){
|
||||
this.data = data;
|
||||
int len = data.array().length + 8 + 2;
|
||||
header.put(0, (byte) (len / 256));
|
||||
header.put(1, (byte) (len % 256));
|
||||
}
|
||||
|
||||
|
||||
public ByteBuffer pack(){
|
||||
ByteBuffer bb = ByteBuffer.allocate(MAX_PACKAGE_LEN);
|
||||
// 长度占位
|
||||
bb.put(length);
|
||||
// head 占位
|
||||
bb.put(header);
|
||||
// command 占位
|
||||
bb.put(command);
|
||||
// data
|
||||
bb.put(data);
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package com.sunyard.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class CoderUtil {
|
||||
|
||||
public static byte[] EToA = hexToBytes(getEDBToAsc());
|
||||
public static byte[] AToE = hexToBytes(getAscToEDB());
|
||||
|
||||
public static String getAscToEDB() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("00010203372D2E2F1605250B0C0D0E0F");
|
||||
sb.append("101112133C3D322618193F271C1D1E1F");
|
||||
sb.append("405A7F7B5B6C507D4D5D5C4E6B604B61");
|
||||
sb.append("F0F1F2F3F4F5F6F7F8F97A5E4C7E6E6F");
|
||||
sb.append("7CC1C2C3C4C5C6C7C8C9D1D2D3D4D5D6");
|
||||
sb.append("D7D8D9E2E3E4E5E6E7E8E9ADE0BD5F6D");
|
||||
sb.append("79818283848586878889919293949596");
|
||||
sb.append("979899A2A3A4A5A6A7A8A9C04FD0A107");
|
||||
sb.append("202122232415061728292A2B2C090A1B");
|
||||
sb.append("30311A333435360838393A3B04143EE1");
|
||||
sb.append("41424344454647484951525354555657");
|
||||
sb.append("58596263646566676869707172737475");
|
||||
sb.append("767778808A8B8C8D8E8F909A9B9C9D9E");
|
||||
sb.append("9FA0AAABAC4AAEAFB0B1B2B3B4B5B6B7");
|
||||
sb.append("B8B9BABBBC6ABEBFCACBCCCDCECFDAdB");
|
||||
sb.append("DCDDDEDFEAEBECEDEEEFFAFBFCFDFEFF");
|
||||
return sb.toString(); }
|
||||
|
||||
public static String getEDBToAsc() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("000102039C09867F978D8E0B0C0D0E0F");
|
||||
sb.append("101112139D8508871819928F1C1D1E1F");
|
||||
sb.append("80818283840A171B88898A8B8C050607");
|
||||
sb.append("909116939495960498999A9B14159E1A");
|
||||
sb.append("20A0A1A2A3A4A5A6A7A8D52E3C282B7C");
|
||||
sb.append("26A9AAABACADAEAFB0B121242A293B5E");
|
||||
sb.append("2D2FB2B3B4B5B6B7B8B9E52C255F3E3F");
|
||||
sb.append("BABBBCBDBEBFC0C1C2603A2340273D22");
|
||||
sb.append("C3616263646566676869C4C5C6C7C8C9");
|
||||
sb.append("CA6A6B6C6D6E6F707172CBCCCDCECFD0");
|
||||
sb.append("D17E737475767778797AD2D3D45BD6D7");
|
||||
sb.append("D8D9DADBDCDDDEDFE0E1E2E3E45DE6E7");
|
||||
sb.append("7B414243444546474849E8E9EAEBECED");
|
||||
sb.append("7D4A4B4C4D4E4F505152EEEFF0F1F2F3");
|
||||
sb.append("5C9F535455565758595AF4F5F6F7F8F9");
|
||||
sb.append("30313233343536373839FAFBFCFDFEFF");
|
||||
return sb.toString(); }
|
||||
|
||||
public static byte[] hexToBytes(char[] hex) {
|
||||
int length = hex.length / 2;
|
||||
byte[] raw = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
int high = Character.digit(hex[i * 2], 16);
|
||||
int low = Character.digit(hex[i * 2 + 1], 16);
|
||||
int value = (high << 4) | low;
|
||||
if (value > 127) value -= 256; raw[i] = (byte) value; }
|
||||
return raw; }
|
||||
|
||||
public static byte[] hexToBytes(String hex) { return hexToBytes(hex.toCharArray()); }
|
||||
|
||||
/**
|
||||
* byte :: ASCII->EBCDIC
|
||||
*/
|
||||
public static int ASCIIToEBCDIC(int ascii) {
|
||||
return AToE[ascii & 0xff] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte :: EBCDIC->ASCII
|
||||
*/
|
||||
public static int EBCDICToASCII(int ebcdic) {
|
||||
return EToA[ebcdic & 0xff] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte[] :: ASCII->EBCDIC
|
||||
*/
|
||||
public static byte[] ASCIIToEBCDIC(byte[] ascii) {
|
||||
byte[] tobytes = new byte[ascii.length];
|
||||
for (int i = 0; i < ascii.length; i++)
|
||||
tobytes[i] = (byte) ASCIIToEBCDIC(ascii[i]);
|
||||
return tobytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接在原数据上修改
|
||||
* byte[] :: ASCII->EBCDIC
|
||||
*/
|
||||
public static byte[] ASCIIToEBCDICFIX(byte[] ascii, int from) {
|
||||
for (int i = from; i < ascii.length; i++)
|
||||
ascii[i] = (byte) ASCIIToEBCDIC(ascii[i]);
|
||||
return ascii;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte[] :: EBCDIC->ASCII
|
||||
*/
|
||||
public static byte[] EBCDICToASCII(byte[] ebcdic) {
|
||||
byte[] tobytes = new byte[ebcdic.length];
|
||||
for (int i = 0; i < ebcdic.length; i++)
|
||||
tobytes[i] = (byte) EBCDICToASCII(ebcdic[i]);
|
||||
return tobytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* byte[] :: EBCDIC->ASCII
|
||||
* 直接修改原数据
|
||||
*/
|
||||
public static byte[] EBCDICToASCIIFIX(byte[] ebcdic, int from) {
|
||||
for (int i = from; i < ebcdic.length; i++)
|
||||
ebcdic[i] = (byte) EBCDICToASCII(ebcdic[i]);
|
||||
return ebcdic;
|
||||
}
|
||||
|
||||
/**
|
||||
* String :: ASCII->EBCDIC
|
||||
*/
|
||||
public static String ASCIIToEBCDIC(String ascii)
|
||||
throws Exception
|
||||
{
|
||||
return new String(ASCIIToEBCDIC(ascii.getBytes("iso-8859-1")), "iso-8859-1");
|
||||
}
|
||||
|
||||
/**
|
||||
* String :: EBCDIC->ASCII
|
||||
*/
|
||||
public static String EBCDICToASCII(String ebcdic)
|
||||
throws Exception
|
||||
{
|
||||
return new String(EBCDICToASCII(ebcdic.getBytes("iso-8859-1")),"iso-8859-1");
|
||||
}
|
||||
|
||||
/**
|
||||
* File :: ASCII->EBCDIC
|
||||
*/
|
||||
public static void ASCIIToEBCDIC(String fromfile, String tofile) {
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(new File(fromfile));
|
||||
FileOutputStream out = new FileOutputStream(new File(tofile));
|
||||
int tempint, i = 0;
|
||||
byte[] tempbytes = new byte[in.available()];
|
||||
while ((tempint = in.read()) != -1)
|
||||
tempbytes[i++] = (byte) tempint;
|
||||
out.write(ASCIIToEBCDIC(tempbytes));
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* File :: EBCDIC->ASCII
|
||||
*/
|
||||
public static void EBCDICToASCII(String fromfile, String tofile) {
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(new File(fromfile));
|
||||
FileOutputStream out = new FileOutputStream(new File(tofile));
|
||||
int tempint, i = 0;
|
||||
byte[] tempbytes = new byte[in.available()];
|
||||
while ((tempint = in.read()) != -1)
|
||||
tempbytes[i++] = (byte) tempint;
|
||||
out.write(EBCDICToASCII(tempbytes));
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user