增加及修改文件以适应RSA密钥签名验签功能
This commit is contained in:
@@ -132,6 +132,18 @@ public interface SydGenApi {
|
||||
*/
|
||||
RetWrap SM2GenSessionKey(String publicKey);
|
||||
|
||||
|
||||
/**
|
||||
* 此函数用于会话密钥的产生,用于发起端。
|
||||
* 加密机产生随机会话密钥,输出两类密文:
|
||||
* 1、 RSA公钥加密的密文,用于密钥的传递。
|
||||
* 2、 本地 LMK 加密,用于本地应用数据的加解密。
|
||||
*
|
||||
* @param publicKey 公钥串,DER 编码,HEX 格式。
|
||||
* @return CipherKey 公钥加密的会话密钥,DER 编码,HEX 格式, SessionKey 本地LMK 加密的会话密钥,HEX 格式 , KCV 会话密钥的检验值,HEX 格式,长度为 16H
|
||||
*/
|
||||
RetWrap RSAGenSessionKey(String publicKey);
|
||||
|
||||
/**
|
||||
* 生成数字信封
|
||||
* @param publicKey 公钥
|
||||
@@ -228,6 +240,8 @@ public interface SydGenApi {
|
||||
*/
|
||||
RetWrap generateDEByDn(String certSerial, byte[] oData);
|
||||
|
||||
RetWrap generateDEByDn(int alg,String certSerial, byte[] oData);
|
||||
|
||||
/**
|
||||
* 产生对称密钥,通过公钥加密生成网联格式的数字信封。
|
||||
|
||||
@@ -325,6 +339,21 @@ public interface SydGenApi {
|
||||
*/
|
||||
RetWrap decryptDE(boolean pFlag, int model, byte[] certSerial, String pCipherKey);
|
||||
|
||||
/**
|
||||
* 接收用RSA私钥解密数字信封,还原对称密钥。
|
||||
*
|
||||
* @param pFlag 输入。 p标识,如果为true,则传入R
|
||||
* @param model 输入。 证书模式,0:证书序号,1:证书 DN
|
||||
* @param certSerial 输入。 对方 X509 证书的序列号或DN。
|
||||
* @param pCipherKey 输入。 公钥加密的会话密钥,BASE64 编码
|
||||
* @return RetWrap 包含 SessionKey KCV
|
||||
* oData 如果有机构码的话会返回原数据
|
||||
* SessionKey 输出。 本地LMK 加密的会话密钥,格式为:密钥类型|密钥密文,比如:02|密钥密文
|
||||
* KCV 会话密钥的检验值,HEX 格式,长度为 36H。
|
||||
* orgCode 如果有机构码的话会返回机构码
|
||||
*/
|
||||
RetWrap decryptDERSA(boolean pFlag, int model, byte[] certSerial, String pCipherKey);
|
||||
|
||||
/**
|
||||
* 产生要求长度的随即数据串,可用于身份认证
|
||||
*
|
||||
|
||||
@@ -28,6 +28,18 @@ interface SydNakedSVApi {
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
/**
|
||||
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制裸签名(遵循 PKCS#1)
|
||||
* 人行项目增加RSA
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public byte[] SYD_NakedSign(
|
||||
int rFlag,
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
@@ -42,8 +54,22 @@ interface SydNakedSVApi {
|
||||
byte[] sign,
|
||||
String sCertDN
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 使用指定的证书 DN,对指定的原始数据编制裸验签(遵循PKCS#1)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
public boolean SYD_NakedVerify(
|
||||
int rFlag,
|
||||
byte[] orgData,
|
||||
byte[] sign,
|
||||
String sCertDN
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 带原文的签名验签
|
||||
*/
|
||||
@@ -182,6 +208,19 @@ interface SydAttachedSVApi {
|
||||
String attachedSign(byte[] orgData, String sCertDN) throws UnsupportedEncodingException;
|
||||
byte[] attachedSignC(byte[] orgData, String sCertDN);
|
||||
|
||||
|
||||
/**
|
||||
* 人行项目需要需要支持RSA
|
||||
* 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
|
||||
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制带公钥证书的数字签名(遵循 PKCS#7)。
|
||||
*
|
||||
* @param orgData 待签名数据
|
||||
* @param sCertDN 证书DN
|
||||
* @return
|
||||
* 符合PKCS7标准的签名结果
|
||||
*/
|
||||
String attachedSign(int rFlag,byte[] orgData, String sCertDN) throws UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
|
||||
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
|
||||
@@ -190,6 +229,17 @@ interface SydAttachedSVApi {
|
||||
* @return true 验签通过 false 验签失败
|
||||
*/
|
||||
boolean attachedVerify(String sign);
|
||||
|
||||
/**
|
||||
* 带公钥证书与原始数据的数字签名验签(遵循 PKCS#7)
|
||||
* 对指定的原始数据核验其带公钥证书签名。如签名有效(含证书无效)且需返回签名者公钥证书信息时,同时返回签名者公钥证书信息。
|
||||
*
|
||||
* @param sign 已签名数据
|
||||
* @return true 验签通过 false 验签失败
|
||||
*/
|
||||
boolean attachedVerify(int rFlag,String sign);
|
||||
|
||||
|
||||
boolean attachedVerify(byte[] sign);
|
||||
|
||||
/**
|
||||
@@ -254,6 +304,19 @@ interface SydDetachedSVApi {
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
/**
|
||||
* 人行项目需要RSA支持
|
||||
* 通过指定的私钥对指定的原始数据编制带公钥证书的数字签名(遵循PKCS#7)
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sCertDN 签名者证书 DN
|
||||
* @return 签名数据
|
||||
*/
|
||||
public String SYD_DetachedSign(
|
||||
int rFlag,
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -361,6 +424,23 @@ interface SydDetachedSVApi {
|
||||
byte[] orgData,
|
||||
String sign);
|
||||
|
||||
/**
|
||||
* 对指定的原始数据核验其带公钥证书签名(PKCS#7)
|
||||
* 数据模式可选 DATA_HASH 或 DATA_ORIGIN
|
||||
*
|
||||
*
|
||||
* @param rFlag RSA标识
|
||||
* @param dataType 输入的数据为 HASH 后的数据 DATA_HASH = 0 ,输入的数据为原始数据库 DATA_ORIGIN = 1
|
||||
* @param orgData 待签名的原始数据
|
||||
* @param sign 签名数据
|
||||
* @return 验签是否通过
|
||||
*/
|
||||
boolean detachedVerify(
|
||||
int rFlag,
|
||||
int dataType,
|
||||
byte[] orgData,
|
||||
String sign);
|
||||
|
||||
/**
|
||||
* 带公钥证书与签名属性的数字签名验签(遵循 PKCS#7)
|
||||
* @param dataType 数据类型:0,hash 模式,1为非hash模式
|
||||
|
||||
@@ -18,12 +18,14 @@ public class ASN1Util {
|
||||
ASN1Sequence seq = ASN1Sequence.getInstance( Util.decodeBase64( sign ) );
|
||||
ASN1TaggedObject tag = (ASN1TaggedObject) seq.getObjectAt(1).toASN1Primitive();
|
||||
ASN1Sequence seq2 = (ASN1Sequence) tag.getObject();
|
||||
ASN1Sequence seq3 = (ASN1Sequence) seq2.getObjectAt( 2 ).toASN1Primitive();
|
||||
ASN1TaggedObject tag2 = (ASN1TaggedObject) seq3.getObjectAt( 1 );
|
||||
DEROctetString o = (DEROctetString) tag2.getObject();
|
||||
ret.put( "orgData", o.getOctets() );
|
||||
|
||||
|
||||
ASN1Sequence seq3 = null;
|
||||
try {
|
||||
seq3 = (ASN1Sequence) seq2.getObjectAt( 2 ).toASN1Primitive();
|
||||
ASN1TaggedObject tag2 = (ASN1TaggedObject) seq3.getObjectAt( 1 );
|
||||
DEROctetString o = (DEROctetString) tag2.getObject();
|
||||
ret.put( "orgData", o.getOctets() );
|
||||
} catch (Exception e) {
|
||||
}
|
||||
ASN1TaggedObject tag3 = (ASN1TaggedObject) seq2.getObjectAt(3).toASN1Primitive();
|
||||
ASN1Sequence seq4 = (ASN1Sequence) tag3.getObject();
|
||||
ret.put("cert", CertUtil.encodeBase64(seq4.getEncoded()));
|
||||
|
||||
@@ -76,7 +76,15 @@ public class CertUtil {
|
||||
* @return true 国密, false 非国密
|
||||
*/
|
||||
public static boolean isSM2Cert(String cert) throws CertificateException, NoSuchProviderException {
|
||||
X509Certificate certificate = convertToX509Cert(cert);
|
||||
String pemCert;
|
||||
if(cert.contains("-----BEGIN CERTIFICATE-----")){
|
||||
pemCert =cert;
|
||||
}else {
|
||||
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
|
||||
String end_cert = "\n-----END CERTIFICATE-----";
|
||||
pemCert = cert_begin + cert + end_cert;
|
||||
}
|
||||
X509Certificate certificate = convertToX509Cert(pemCert);
|
||||
String signAlg = certificate.getSigAlgName();
|
||||
return signAlg.toUpperCase().indexOf("SM2") >= 0;
|
||||
}
|
||||
@@ -89,7 +97,16 @@ public class CertUtil {
|
||||
*/
|
||||
public static boolean isSignedBySM2Cert(String pkcs7) throws IOException, CertificateException, NoSuchProviderException {
|
||||
RetWrap ret = ASN1Util.takeOutOriginDataFromPKCS7Sign(pkcs7);
|
||||
return isSM2Cert((String) ret.get("cert"));
|
||||
//return isSM2Cert((String) ret.get("cert"));
|
||||
String cert =(String) ret.get("cert");
|
||||
if(cert.contains("-----BEGIN CERTIFICATE-----")){
|
||||
return isSM2Cert(cert);
|
||||
}else{
|
||||
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
|
||||
String end_cert = "\n-----END CERTIFICATE-----";
|
||||
String pemCert = cert_begin + cert + end_cert;
|
||||
return isSM2Cert(pemCert);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -438,6 +438,66 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] SYD_NakedSign(int rFlag, byte[] orgData, String sCertDN) {
|
||||
Proto8003 proto = new Proto8003();
|
||||
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());
|
||||
if(rFlag ==1){
|
||||
data.put("rFlag", 'M');
|
||||
}
|
||||
if(rFlag ==2){
|
||||
data.put("rFlag", 'S');
|
||||
}
|
||||
if(rFlag ==3){
|
||||
data.put("rFlag", 'R');
|
||||
}
|
||||
data.put("signatureDataType$option", 1);
|
||||
data.put("DN", dn);
|
||||
data.put("signData", 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 ((PacketSection) ret.get("signature")).getBytes();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean SYD_NakedVerify(byte[] orgData, byte[] sign, String sCertDN) {
|
||||
Proto8004 proto = new Proto8004();
|
||||
@@ -493,6 +553,70 @@ public class SydApi4j implements SydApi {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean SYD_NakedVerify(int rFlag,byte[] orgData, byte[] sign, String sCertDN) {
|
||||
Proto8004 proto = new Proto8004();
|
||||
|
||||
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());
|
||||
if(rFlag ==1){
|
||||
data.put("rFlag", 'M');
|
||||
}
|
||||
if(rFlag ==2){
|
||||
data.put("rFlag", 'S');
|
||||
}
|
||||
if(rFlag ==3){
|
||||
data.put("rFlag", 'R');
|
||||
}
|
||||
data.put("signatureDataType$option", 1);
|
||||
data.put("DN", dn);
|
||||
data.put("odata", orgData);
|
||||
data.put("signature", sign);
|
||||
data.put("returnSign$option", 0);
|
||||
// 渲染发送
|
||||
ByteBuffer bb = proto.rend(packet);
|
||||
|
||||
synchronized (this) {
|
||||
byte[] b = syncSend(bb);
|
||||
|
||||
// 响应解析
|
||||
bb = syncRead(b);
|
||||
}
|
||||
|
||||
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]))) {
|
||||
SydApiException e = new SydApiException(error.getInfo(), error.autoInt());
|
||||
println("验签失败=" + e.toString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String sm3AndDetachedSign(byte[] orgData, String publicKey, String sCertDN) {
|
||||
@@ -743,6 +867,71 @@ public class SydApi4j implements SydApi {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean detachedVerify(int rFlag,int dataType, byte[] orgData, String sign) {
|
||||
Proto8006 proto = new Proto8006();
|
||||
|
||||
// 填充数据
|
||||
HashMap<String, Object> packet = new HashMap<String, Object>();
|
||||
HashMap<String, Object> data = new HashMap<String, Object>();
|
||||
packet.put("data", data);
|
||||
PacketSN sn = PacketSN.gen();
|
||||
if(rFlag ==1){//RSA证书
|
||||
data.put("rFlag", 'D');
|
||||
}
|
||||
if(rFlag ==2){
|
||||
data.put("rFlag", 'O');
|
||||
}
|
||||
if(rFlag ==3){
|
||||
data.put("rFlag", 'U');
|
||||
}
|
||||
packet.put("header", sn.getSn().array());
|
||||
|
||||
|
||||
if (dataType == DATA_HASH) {
|
||||
if(rFlag ==1){//RSA证书
|
||||
data.put("hashFlag", 'M');
|
||||
}
|
||||
if(rFlag ==2){
|
||||
data.put("hashFlag", 'S');
|
||||
}
|
||||
if(rFlag ==3){
|
||||
data.put("hashFlag", 'R');
|
||||
}
|
||||
data.put("hash", orgData);
|
||||
} else {
|
||||
data.put("originData", orgData);
|
||||
}
|
||||
data.put("signData", sign.getBytes());
|
||||
data.put("flag$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]))) {
|
||||
SydApiException e = new SydApiException(error.getInfo(), error.autoInt());
|
||||
println("验签失败=" + e.toString());
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509 detachedVerifyAndGetX509(int dataType, byte[] orgData, String sign) {
|
||||
|
||||
@@ -852,6 +1041,90 @@ public class SydApi4j implements SydApi {
|
||||
return detachedSign(DATA_ORIGIN, orgData, sCertDN);
|
||||
}
|
||||
|
||||
|
||||
public String SYD_RSA_DetachedSign_HA(
|
||||
int pFlag,
|
||||
byte[] orgData,
|
||||
String sCertDN
|
||||
) {
|
||||
return detachedSign(pFlag,DATA_ORIGIN, orgData, sCertDN);
|
||||
}
|
||||
|
||||
|
||||
public String detachedSign(int rFlag,int dataType, byte[] orgData, String sCertDN) {
|
||||
Proto8005 proto = new Proto8005();
|
||||
byte[] dn = new byte[256];
|
||||
byte[] s = null;
|
||||
try {
|
||||
sCertDN = DnUtil.verifyDn( sCertDN );
|
||||
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());
|
||||
if(rFlag ==1){//RSA证书加签方法
|
||||
data.put("rFlag", 'M');
|
||||
}
|
||||
if(rFlag ==2){
|
||||
data.put("rFlag", 'S');
|
||||
}
|
||||
if(rFlag ==3){
|
||||
data.put("rFlag", 'R');
|
||||
}
|
||||
data.put("DN", dn);
|
||||
if (dataType == DATA_HASH) {
|
||||
if(rFlag==1){
|
||||
data.put("hashFlag", 'M');
|
||||
}
|
||||
if(rFlag==2){
|
||||
data.put("hashFlag", 'S');
|
||||
}
|
||||
if(rFlag==3){
|
||||
data.put("hashFlag", 'R');
|
||||
}
|
||||
data.put("hash", orgData);
|
||||
} else {
|
||||
data.put("infoData", 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 ((PacketSection) ret.get("signature")).getString();
|
||||
|
||||
}
|
||||
|
||||
// 测试通过
|
||||
@Override
|
||||
public boolean SYD_SM2_DetachedVerify_HA(
|
||||
@@ -872,6 +1145,11 @@ public class SydApi4j implements SydApi {
|
||||
return SYD_SM2_DetachedSign_HA(orgData, sCertDN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String SYD_DetachedSign(int rFlag,byte[] orgData, String sCertDN) {
|
||||
return SYD_RSA_DetachedSign_HA(rFlag,orgData, sCertDN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509 SYD_Get_X509_CertInfo_HA(
|
||||
byte[] orgData,
|
||||
@@ -994,6 +1272,7 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
|
||||
r.put("certDNs", certs.toArray(new String[0]));
|
||||
// r.put("certDNlist", certs);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -2423,6 +2702,15 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetWrap generateDEByDn(int alg,String certSerial, byte[] oData) {
|
||||
if ( oData.length <= 4 * 1024 ) {
|
||||
return generateDEByDnHsmRSA(alg, certSerial, oData );
|
||||
} else {
|
||||
return generateDEByDnSoftRSA( alg,certSerial, oData );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RetWrap generateDEByDnHsm(String certSerial, byte[] oData) {
|
||||
|
||||
@@ -2437,6 +2725,19 @@ public class SydApi4j implements SydApi {
|
||||
return generateDE(dnBytes, 3, 1, oData);
|
||||
}
|
||||
|
||||
public RetWrap generateDEByDnHsmRSA(int alg,String certSerial, byte[] oData) {
|
||||
|
||||
certSerial = DnUtil.verifyDn( certSerial );
|
||||
|
||||
byte[] dnBytes = null;
|
||||
try {
|
||||
dnBytes = certSerial.getBytes("gbk");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return generateDE(dnBytes, 0, 1, oData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetWrap generateDE(byte[] certSerial, int alg, int model, byte[] oData) {
|
||||
Proto6A proto = new Proto6A();
|
||||
@@ -2454,7 +2755,7 @@ public class SydApi4j implements SydApi {
|
||||
data.put("certificateDn", certSerial);
|
||||
}
|
||||
|
||||
if (alg == 3) {
|
||||
if (alg == 3 || alg == 0 ) {
|
||||
data.put("orgData", oData);
|
||||
}
|
||||
|
||||
@@ -2562,6 +2863,19 @@ public class SydApi4j implements SydApi {
|
||||
return decryptDE(true, 1, dnBytes, pCipherKey);
|
||||
}
|
||||
|
||||
public RetWrap decryptDEByDNHsmRSA(String certSerial, String pCipherKey) {
|
||||
|
||||
certSerial = DnUtil.verifyDn( certSerial );
|
||||
|
||||
byte[] dnBytes = null;
|
||||
try {
|
||||
dnBytes = certSerial.getBytes("gbk");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return decryptDERSA(true, 1, dnBytes, pCipherKey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过 DN 查找证书
|
||||
@@ -2629,7 +2943,7 @@ public class SydApi4j implements SydApi {
|
||||
byte[] len = new byte[2];
|
||||
bb.get(len);
|
||||
|
||||
int l = len[0] * 256 + len[1];
|
||||
int l = Util.b2i(len); // len[0] * 256 + len[1];
|
||||
byte[] cert = new byte[l];
|
||||
bb.get(cert);
|
||||
|
||||
@@ -2706,6 +3020,70 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
public RetWrap generateDEByDnSoftRSA(int alg,String certSerial, byte[] oData) {
|
||||
|
||||
certSerial = DnUtil.verifyDn( certSerial );
|
||||
|
||||
RetWrap ret = new RetWrap();
|
||||
byte[] dnBytes = null;
|
||||
try {
|
||||
dnBytes = certSerial.getBytes("gbk");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 查询完整证书
|
||||
String cert = getCertByDn(dnBytes);
|
||||
println("cert=" + cert);
|
||||
|
||||
try {
|
||||
X509Certificate x509 = getX509Certificate(new ByteArrayInputStream(cert.getBytes()));
|
||||
X500Principal issuser = x509.getIssuerX500Principal();
|
||||
|
||||
String pk = ByteUtils.toHexString(x509.getPublicKey().getEncoded());
|
||||
if (!pk.startsWith("03420004")) {
|
||||
int i = pk.indexOf("03420004");
|
||||
if ( i >= 0 ) {
|
||||
pk = pk.substring(i);
|
||||
} else {
|
||||
pk = "03420004" + pk;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 生成会话密钥
|
||||
ret = RSAGenSessionKey(pk);
|
||||
String ciperKey = ret.get(SydApi.RET_CIPHER_KEY).toString();
|
||||
String sessionKeyByLMK = (String) ret.get(SydApi.RET_SESSION_KEY );
|
||||
ret.put(SydApi.RET_SESSION_KEY , sessionKeyByLMK.getBytes() );
|
||||
|
||||
println("ciperKey=" + ciperKey);
|
||||
println("sessionKeyByLMK=" + sessionKeyByLMK);
|
||||
|
||||
// 加密数据
|
||||
byte[] iv = new byte[32];
|
||||
Arrays.fill(iv, (byte) 0x30);
|
||||
RetWrap retWrap = SYMEnDeData(true, 2, sessionKeyByLMK, 1, 1, oData, iv, 0);
|
||||
byte[] enData = (byte[]) retWrap.get("msg_all");
|
||||
|
||||
// 组织格式
|
||||
ContentInfo cms = genCMSEnvelopedData( Util.hexString2Bytes(ciperKey), enData,
|
||||
x509.getSerialNumber().toString(16) ,
|
||||
dnToMap(issuser.getName() )
|
||||
);
|
||||
|
||||
ret.put(SydApi.RET_CIPHER_KEY, Util.encodeBase64(cms.getEncoded()).getBytes() );
|
||||
|
||||
return ret;
|
||||
|
||||
} catch (SydApiException syde) {
|
||||
throw syde;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new SydApiException("生成数字信封错误", -5);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, String>dnToMap(String dn) {
|
||||
Map<String, String>map = new HashMap<String, String>();
|
||||
String[] kvs = dn.split(",");
|
||||
@@ -2787,6 +3165,15 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public RetWrap decryptDEByDN(int alg,String certSerial, byte[] pCipherKey){
|
||||
if ( pCipherKey.length <= 4 * 1024 ) {
|
||||
return decryptDEByDNHsmRSA( certSerial, new String(pCipherKey) );
|
||||
} else {
|
||||
return decryptDEByDNSoftRSA( certSerial, new String(pCipherKey) );
|
||||
}
|
||||
}
|
||||
|
||||
public RetWrap decryptDEByDNSoft(String certSerial, String pCipherKey) {
|
||||
|
||||
certSerial = DnUtil.verifyDn( certSerial );
|
||||
@@ -2826,6 +3213,46 @@ public class SydApi4j implements SydApi {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public RetWrap decryptDEByDNSoftRSA(String certSerial, String pCipherKey) {
|
||||
|
||||
certSerial = DnUtil.verifyDn( certSerial );
|
||||
|
||||
byte[] dnBytes = null;
|
||||
try {
|
||||
dnBytes = certSerial.getBytes("gbk");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
RetWrap ret = null;
|
||||
|
||||
try {
|
||||
ret = deCMSEnvelopedData( Util.decodeBase64( pCipherKey ) );
|
||||
} catch ( Exception e) {
|
||||
throw new IllegalArgumentException("数字信封解封格式错误");
|
||||
}
|
||||
|
||||
byte[] sessionKeyDer = (byte[]) ret.get("sessionKeyDer");
|
||||
byte[] enData = (byte[]) ret.get("enData");
|
||||
|
||||
// 解密原文
|
||||
byte[] iv = (byte[]) ret.get("iv"); //new byte[32];
|
||||
// Arrays.fill(iv, (byte) 0x30);
|
||||
iv = Util.bytes2HexString( iv ).getBytes();
|
||||
|
||||
// 解密会话密钥
|
||||
ret = decryptDERSA(true, 1, dnBytes, Util.encodeBase64(sessionKeyDer) );
|
||||
String sessionKey = new String((byte[]) ret.get("SessionKey") );
|
||||
|
||||
RetWrap retWrap = SYMEnDeData(false, 2, sessionKey, 1, 1, enData, iv, 0);
|
||||
byte[] data = (byte[]) retWrap.get("msg_all");
|
||||
|
||||
ret.put("oData", data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 测试通过
|
||||
@Override
|
||||
@@ -2894,6 +3321,74 @@ public class SydApi4j implements SydApi {
|
||||
return rw;
|
||||
}
|
||||
|
||||
// 测试通过
|
||||
@Override
|
||||
public RetWrap decryptDERSA(boolean pFlag, int model, byte[] certSerial, String pCipherKey) {
|
||||
// 获取协议
|
||||
//ProtocolRender render = pset.getProtocolReqRender("6B");
|
||||
// 与6B相同
|
||||
Proto6BXF proto = new Proto6BXF();
|
||||
// 填充数据
|
||||
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>();
|
||||
if (pFlag) {
|
||||
data.put("pFlag", "R");
|
||||
}
|
||||
data.put("certificateModel$option", model);
|
||||
|
||||
if (model == 0) {
|
||||
data.put("certificateSn", certSerial);
|
||||
} else {
|
||||
data.put("certificateDn", certSerial);
|
||||
}
|
||||
data.put("key", pCipherKey);
|
||||
data.put("keyType", "X");
|
||||
packet.put("data", data);
|
||||
|
||||
// 渲染发送
|
||||
ByteBuffer bb = proto.rend(packet);
|
||||
synchronized (this) {
|
||||
// 响应解析
|
||||
bb = syncRead(syncSend(bb));
|
||||
}
|
||||
|
||||
//ProtocolParser parser = pset.getProtocolResParse();
|
||||
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");
|
||||
if (!"00".equals(error.getString())) {
|
||||
throw new SydApiException(error.getInfo(), error.autoInt());
|
||||
}
|
||||
RetWrap rw = new RetWrap();
|
||||
|
||||
if (pFlag) {
|
||||
rw.put("oData", ((PacketSection) ret.get("oData")).getBytes());
|
||||
}
|
||||
|
||||
int orgCodeLen = Util.a2i(((PacketSection) ret.get("orgCodeLen")).getBytes(), 10);
|
||||
if (orgCodeLen != 0) {
|
||||
rw.put("orgCode", ((PacketSection) ret.get("orgCode")).getBytes());
|
||||
}
|
||||
|
||||
rw.put(SydApi.RET_SESSION_KEY, (((PacketSection) ret.get("lmkHead")).getString() +
|
||||
((PacketSection) ret.get("lmk")).getString()).getBytes()
|
||||
);
|
||||
|
||||
rw.put(SydApi.RET_KCV, ((PacketSection) ret.get("keyCheck")).getBytes());
|
||||
|
||||
return rw;
|
||||
}
|
||||
|
||||
|
||||
// 测试通过
|
||||
@Override
|
||||
public String GenerateRandom(int nRandomSize) {
|
||||
@@ -5443,6 +5938,57 @@ public class SydApi4j implements SydApi {
|
||||
return rw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetWrap RSAGenSessionKey(String publicKey) {
|
||||
// 获取协议
|
||||
//ProtocolRender render = pset.getProtocolReqRender("72");
|
||||
Proto72 proto = new Proto72();
|
||||
// 填充数据
|
||||
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("pFlag", "R");
|
||||
data.put("publicKey", Util.hexString2Bytes(publicKey));
|
||||
data.put("lmk", "L");
|
||||
packet.put("data", data);
|
||||
|
||||
// 渲染发送 耗时长
|
||||
ByteBuffer bb = proto.rend(packet);
|
||||
synchronized (this) {
|
||||
|
||||
// 响应解析
|
||||
bb = syncRead(syncSend(bb));
|
||||
}
|
||||
|
||||
//ProtocolParser parser = pset.getProtocolResParse();
|
||||
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");
|
||||
if (!"00".equals(error.getString())) {
|
||||
throw new SydApiException(error.getInfo(), error.autoInt());
|
||||
}
|
||||
RetWrap rw = new RetWrap();
|
||||
rw.put(SydApi.RET_CIPHER_KEY,
|
||||
Util.bytes2HexString( ((PacketSection) ret.get("key")).getBytes() )
|
||||
);
|
||||
|
||||
rw.put(SydApi.RET_SESSION_KEY, (((PacketSection) ret.get("lmkHead")).getString() +
|
||||
((PacketSection) ret.get("lmk")).getString())
|
||||
);
|
||||
|
||||
rw.put(SydApi.RET_KCV, ((PacketSection) ret.get("keyCheck")).getString());
|
||||
|
||||
return rw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成数字信封
|
||||
*
|
||||
@@ -8330,12 +8876,12 @@ public class SydApi4j implements SydApi {
|
||||
* @param hashType HASH类型。0: SHA1,1: SHA256,2: MD5
|
||||
* @param packSn 消息块号。0=仅一块,1=第一块,2=中间块,3=最后块
|
||||
* @param msg 二进制的消息块
|
||||
* @param filterData 过渡消息数据,只对“消息块号”为 2、3 时有效
|
||||
* @param filterData 过渡消息数据,只对“消息块号”为 2、1 时有效
|
||||
* @return filterData: 过渡消息数据.只对“消息块号”为 2、1 时有效
|
||||
* hash: hash
|
||||
*/
|
||||
// 测试通过
|
||||
public RetWrap conutHash(int hashType, int packSn, byte[] msg, byte[] filterData) {
|
||||
public RetWrap countHash(int hashType, int packSn, byte[] msg, byte[] filterData) {
|
||||
Proto7D proto = new Proto7D();
|
||||
HashMap<String, Object> packet = new HashMap();
|
||||
HashMap<String, Object> data = new HashMap();
|
||||
@@ -10756,6 +11302,22 @@ public class SydApi4j implements SydApi {
|
||||
return this.detachedVerify( 0, hash , sign2);
|
||||
}
|
||||
|
||||
private boolean attachedVerifyRSA(int rFlag,String sign){
|
||||
RetWrap ret = null;
|
||||
try {
|
||||
ret = ASN1Util.takeOutOriginDataFromPKCS7Sign( sign );
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("解析 pkcs7 签名格式时错误");
|
||||
}
|
||||
|
||||
byte[] orgData = (byte[]) ret.get("orgData");
|
||||
// byte[] pk = (byte[]) ret.get("pk");
|
||||
// byte[] hash = this.SM3Hash( Util.bytes2HexString( pk ), orgData );
|
||||
String sign2 = (String) ret.get("sign");
|
||||
return this.detachedVerify( rFlag,0, orgData , sign2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
|
||||
@@ -10778,6 +11340,95 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String attachedSign(int rFlag,byte[] orgData, String sCertDN) {
|
||||
//return attachedSignRSA( rFlag, orgData, sCertDN );
|
||||
try {
|
||||
if ( orgData.length > 4096 ) {
|
||||
return attachedSignRSASoft( rFlag,orgData, sCertDN );
|
||||
} else {
|
||||
return attachedSignRSAHsm( rFlag,orgData, sCertDN );
|
||||
}
|
||||
}catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalArgumentException("DN is not in GBK");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String attachedSignRSASoft(int rFlag,byte[] orgData, String sCertDN) throws UnsupportedEncodingException {
|
||||
sCertDN = DnUtil.verifyDn( sCertDN );
|
||||
String pk = this.GetDNPublicKey( SydApi.FOR_SIGN, sCertDN.getBytes("GBK") );
|
||||
try {
|
||||
byte[] hash = this.SM3Hash( pk, orgData );
|
||||
String sign = this.detachedSign(rFlag,0, hash, sCertDN);
|
||||
return ASN1Util.addOriginDataToPKCS7Sign( orgData, sign );
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalArgumentException("解析 pkcs7 签名格式时错误");
|
||||
}
|
||||
}
|
||||
|
||||
public String attachedSignRSAHsm(int rFlag,byte[] orgData, String sCertDN) {
|
||||
sCertDN = DnUtil.verifyDn( sCertDN );
|
||||
|
||||
Proto8018 proto = new Proto8018();
|
||||
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());
|
||||
if(rFlag ==1){
|
||||
data.put("rFlag", 'M');
|
||||
}
|
||||
if(rFlag ==2){
|
||||
data.put("rFlag", 'S');
|
||||
}
|
||||
if(rFlag ==3){
|
||||
data.put("rFlag", 'R');
|
||||
}
|
||||
data.put("DN", dn);
|
||||
data.put("infoData", 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 ((PacketSection) ret.get("signature")).getString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public String attachedSignHsm(byte[] orgData, String sCertDN) {
|
||||
sCertDN = DnUtil.verifyDn( sCertDN );
|
||||
@@ -10842,6 +11493,16 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attachedVerify(int rFlag,String sign) {
|
||||
|
||||
if ( sign.length() > 4096 ) {
|
||||
return attachedVerifyRSA( rFlag,sign );
|
||||
} else {
|
||||
return attachedVerify( sign.getBytes() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean attachedVerify(byte[] sign) {
|
||||
Proto8019 proto = new Proto8019();
|
||||
|
||||
Reference in New Issue
Block a user