打包签名验签

This commit is contained in:
cheney
2022-06-24 11:52:03 +08:00
parent 0c13d0c38a
commit 6cb3072453
6 changed files with 271 additions and 33 deletions
+3 -1
View File
@@ -4,6 +4,8 @@ package com.sunyard.inf;
import com.sunyard.RetWrap;
import com.sunyard.cert.X509;
import java.io.UnsupportedEncodingException;
/**
* 签名验签相关接口
*/
@@ -177,7 +179,7 @@ interface SydAttachedSVApi {
* @return
* 符合PKCS7标准的签名结果
*/
String attachedSign(byte[] orgData, String sCertDN);
String attachedSign(byte[] orgData, String sCertDN) throws UnsupportedEncodingException;
byte[] attachedSignC(byte[] orgData, String sCertDN);
/**
@@ -0,0 +1,67 @@
package com.sunyard.util;
import cn.hutool.core.bean.BeanUtil;
import com.sunyard.RetWrap;
import com.sunyard.proto.R;
import com.sunyard.proto.Util;
import org.bouncycastle.asn1.*;
import java.io.IOException;
public class ASN1Util {
public static RetWrap takeOutOriginDataFromPKCS7Sign(String sign) throws IOException {
RetWrap ret = new RetWrap();
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() );
ASN1TaggedObject tag3 = (ASN1TaggedObject) seq2.getObjectAt(3).toASN1Primitive();
ASN1Sequence seq4 = (ASN1Sequence) tag3.getObject();
ret.put("cert", CertUtil.encodeBase64(seq4.getEncoded()));
ASN1Sequence seq5 = (ASN1Sequence) seq4.getObjectAt( 0 ).toASN1Primitive();
ASN1Sequence seq6 = (ASN1Sequence) seq5.getObjectAt( 6 ).toASN1Primitive();
DERBitString pk = (DERBitString) seq6.getObjectAt( 1 ).toASN1Primitive();
ret.put("pk", pk.getEncoded() );
ASN1Encodable[] elements = seq3.toArray();
ASN1Encodable[] elements2 = new ASN1Encodable[ elements.length - 1];
for ( int i = 0; i < elements.length -1 ; i++ ){
elements2[i] = elements[i];
}
BeanUtil.setProperty( seq3, "elements", elements2);
ret.put("sign", Util.encodeBase64(seq.getEncoded()) );
return ret;
}
public static String addOriginDataToPKCS7Sign( byte[] originData, String sign) throws IOException {
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();
ASN1Encodable[] elements = seq3.toArray();
ASN1Encodable[] elements2 = new ASN1Encodable[ elements.length + 1];
for ( int i = 0; i < elements.length ; i++ ){
elements2[i] = elements[i];
}
elements2[ elements.length ] = new DERTaggedObject(true, 0, new DEROctetString( originData ));
BeanUtil.setProperty( seq3, "elements", elements2);
return Util.encodeBase64(seq.getEncoded());
}
}
@@ -0,0 +1,9 @@
package com.sunyard.util;
import sun.misc.BASE64Encoder;
public class CertUtil {
public static String encodeBase64(byte[] data){
return new BASE64Encoder().encode( data );
}
}
+94 -3
View File
@@ -4960,7 +4960,7 @@ public class SydApi4j implements SydApi {
// 填充数据
PacketSN sn = PacketSN.gen();
final int packLen = 2048;
final int packLen = 4064; // 2048
int loop = msg.length / packLen;
if (msg.length % packLen > 0) {
loop++;
@@ -5016,7 +5016,7 @@ public class SydApi4j implements SydApi {
}
ByteBuffer bb = ByteBuffer.allocate(3000);
ByteBuffer bb = ByteBuffer.allocate(4 * 1024 + 128);
byte[] ret = new byte[2];
bb.put(ret);
@@ -10424,6 +10424,64 @@ public class SydApi4j implements SydApi {
return sign.getBytes();
}
public String attachedSignSoft(byte[] orgData, String sCertDN) throws UnsupportedEncodingException {
String pk = this.GetDNPublicKey( SydApi.FOR_SIGN, sCertDN.getBytes("GBK") );
try {
byte[] hash = this.SM3Hash( pk, orgData );
String sign = this.detachedSign(0, hash, sCertDN);
return ASN1Util.addOriginDataToPKCS7Sign( orgData, sign );
} catch (IOException e) {
e.printStackTrace();
throw new IllegalArgumentException("解析 pkcs7 签名格式时错误");
}
}
private RetWrap attachedVerifySoftGetAll(byte[] sign){
RetWrap ret = null;
try {
ret = ASN1Util.takeOutOriginDataFromPKCS7Sign( new String(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");
boolean pass = this.detachedVerify( 0, hash , sign2);
if ( pass ) {
ret.put("oData", orgData);
String certInfo = (String) ret.get("cert");
certInfo = "-----BEGIN CERTIFICATE-----\r\n" + certInfo;
certInfo = certInfo + "\r\n-----END CERTIFICATE-----\r\n";
X509 x509 = GetX509CertInfo( certInfo );
ret.put("x509", x509);
return ret;
} else {
return null;
}
}
private boolean attachedVerifySoft(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( 0, hash , sign2);
}
/**
* 带公钥证书与原始数据的数字签名(遵循 PKCS#7)
* 使用指定的证书 DN,从加密设备获取对应的私钥证书,对指定的原始数据编制带公钥证书的数字签名(遵循 PKCS#7)。
@@ -10434,6 +10492,19 @@ public class SydApi4j implements SydApi {
*/
@Override
public String attachedSign(byte[] orgData, String sCertDN) {
try {
if ( orgData.length > 4096 ) {
return attachedSignSoft( orgData, sCertDN );
} else {
return attachedSignHsm( orgData, sCertDN );
}
}catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("DN is not in GBK");
}
}
public String attachedSignHsm(byte[] orgData, String sCertDN) {
sCertDN = DnUtil.verifyDn( sCertDN );
Proto8018 proto = new Proto8018();
@@ -10483,9 +10554,17 @@ public class SydApi4j implements SydApi {
return ((PacketSection) ret.get("signature")).getString();
}
public boolean attachedVerifyHsm(String sign) {
return attachedVerify( sign.getBytes() );
}
@Override
public boolean attachedVerify(String sign) {
return attachedVerify( sign.getBytes() );
if ( sign.length() > 4096 ) {
return attachedVerifySoft( sign );
} else {
return attachedVerify( sign.getBytes() );
}
}
@Override
@@ -10568,7 +10647,19 @@ public class SydApi4j implements SydApi {
return attachedVerifyAndGetAll( sign.getBytes() );
}
// 大数据兼容处理
public RetWrap attachedVerifyAndGetAll(byte[] sign) {
if( sign.length > 4096 ) {
return attachedVerifySoftGetAll( sign );
} else {
return attachedVerifyAndGetAllHsm( sign );
}
}
public RetWrap attachedVerifyAndGetAllHsm(byte[] sign) {
Proto8019 proto = new Proto8019();
// 填充数据