增加二维码、条形码签名验签测试
This commit is contained in:
@@ -68,6 +68,11 @@ public class SydApiException extends RuntimeException{
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x8004 : {
|
||||
msg = "证书已过期";
|
||||
break;
|
||||
}
|
||||
|
||||
case 32770:
|
||||
msg = "签名验证错误(P7) ";
|
||||
break;
|
||||
|
||||
@@ -151,6 +151,8 @@ public interface SydCertApi {
|
||||
RetWrap importCert(byte[] certData, byte[] organizationId, CertUsage... us);
|
||||
RetWrap importCert(byte[] certData, byte[] organizationId);
|
||||
|
||||
String importCert(String cert);
|
||||
|
||||
|
||||
/**
|
||||
* 从加密设备中删除指定 DN 的公钥证书
|
||||
|
||||
@@ -240,6 +240,9 @@ public interface SydGenApi {
|
||||
*/
|
||||
RetWrap generateDEByDn(String certSerial, byte[] oData);
|
||||
|
||||
|
||||
RetWrap generateDEByDnICBC(String certSerial,String iv, byte[] oData,int roundmod);
|
||||
|
||||
RetWrap generateDEByDnRSA(int alg,String certSerial, byte[] oData);
|
||||
|
||||
/**
|
||||
@@ -323,6 +326,8 @@ public interface SydGenApi {
|
||||
* orgCode 如果有机构码的话会返回机构码
|
||||
*/
|
||||
RetWrap decryptDEByDN(String certSerial, byte[] pCipherKey);
|
||||
|
||||
RetWrap decryptDEByDNICBC(String certSerial, String IV,String pCipherKey,int roundmod);
|
||||
RetWrap decryptDEByDNRSA(int alg,String certSerial, byte[] pCipherKey);
|
||||
/**
|
||||
* 接收用私钥解密数字信封,还原对称密钥。
|
||||
|
||||
@@ -46,12 +46,14 @@ public class CertUtil {
|
||||
return (X509Certificate) CF.generateCertificate(new ByteArrayInputStream(certificateString.getBytes())); // 将文件流的证书转化为证书类
|
||||
}
|
||||
|
||||
public static String convertToPem(X509Certificate cert) throws CertificateEncodingException {
|
||||
public static String convertToPem(String cert) throws CertificateEncodingException {
|
||||
|
||||
String cert_begin = "-----BEGIN CERTIFICATE-----\n";
|
||||
String end_cert = "\n-----END CERTIFICATE-----";
|
||||
|
||||
byte[] derCert = cert.getEncoded();
|
||||
// byte[] derCert = cert.getEncoded();
|
||||
|
||||
byte[] derCert = cert.getBytes();
|
||||
String pemCertPre = new String(Base64.encode(derCert, true));
|
||||
String pemCert = cert_begin + pemCertPre + end_cert;
|
||||
return pemCert;
|
||||
@@ -98,6 +100,25 @@ public class CertUtil {
|
||||
return signAlg.toUpperCase().indexOf("SM2") >= 0;
|
||||
}
|
||||
|
||||
|
||||
public static String getDN(String 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 = null;
|
||||
try {
|
||||
certificate = convertToX509Cert(pemCert);
|
||||
} catch (Exception e) {
|
||||
throw new SydApiException( 0xC101, e );
|
||||
}
|
||||
return certificate.getSubjectDN().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断 p7 是否是国密证书签的
|
||||
*
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.sunyard.util;
|
||||
|
||||
import com.google.zxing.*;
|
||||
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
|
||||
import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import com.google.zxing.qrcode.QRCodeReader;
|
||||
import com.sunyard.SydApiException;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class QRCodeUtil {
|
||||
|
||||
public static void genQRCode(String data,String filepath){
|
||||
// 图片的尺寸(宽度和高度)
|
||||
int width = 300;
|
||||
int height = 300;
|
||||
|
||||
// 设置二维码的相关参数
|
||||
Hashtable<EncodeHintType, Object> hintMap = new Hashtable<>();
|
||||
hintMap.put(EncodeHintType.MARGIN, 1); // 设置二维码的空白边距
|
||||
|
||||
try {
|
||||
// 创建二维码矩阵
|
||||
BitMatrix bitMatrix = new MultiFormatWriter().encode(
|
||||
data,
|
||||
BarcodeFormat.QR_CODE,
|
||||
width,
|
||||
height,
|
||||
hintMap
|
||||
);
|
||||
|
||||
// 将二维码矩阵转换为图片,并保存
|
||||
File outputFile = new File(filepath);
|
||||
MatrixToImageWriter.writeToFile(bitMatrix, "PNG", outputFile);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error occurred while generating QR code: " + e.getMessage());
|
||||
throw new SydApiException(1001,e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void genBarCode(String data,String filepath){
|
||||
// 图片的尺寸(宽度和高度)
|
||||
int width = 300;
|
||||
int height = 300;
|
||||
|
||||
// 设置二维码的相关参数
|
||||
Hashtable<EncodeHintType, Object> hintMap = new Hashtable<>();
|
||||
hintMap.put(EncodeHintType.MARGIN, 1); // 设置二维码的空白边距
|
||||
|
||||
try {
|
||||
// 生成 Code 128 条形码
|
||||
BitMatrix bitMatrix= new MultiFormatWriter().encode(
|
||||
data,
|
||||
BarcodeFormat.PDF_417,
|
||||
width,
|
||||
height,
|
||||
hintMap
|
||||
);
|
||||
|
||||
// 将二维码矩阵转换为图片,并保存
|
||||
File outputFile = new File(filepath);
|
||||
MatrixToImageWriter.writeToFile(bitMatrix, "PNG", outputFile);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error occurred while generating QR code: " + e.getMessage());
|
||||
throw new SydApiException(1001,e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static String readQRCode(String filepath){
|
||||
// 加载二维码图像
|
||||
File qrCodeImage = new File(filepath);
|
||||
|
||||
// 读取二维码图像
|
||||
BufferedImage bufferedImage = null;
|
||||
try {
|
||||
bufferedImage = ImageIO.read(qrCodeImage);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 使用 ZXing 的 QRCodeReader 进行解码
|
||||
QRCodeReader reader = new QRCodeReader();
|
||||
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
|
||||
try {
|
||||
// 解码二维码
|
||||
Result result = reader.decode(bitmap);
|
||||
|
||||
// 提取二维码中的数据
|
||||
return result.getText();
|
||||
|
||||
} catch (NotFoundException e) {
|
||||
throw new SydApiException(1003,e);
|
||||
} catch (ChecksumException e) {
|
||||
throw new SydApiException(1004,e);
|
||||
} catch (FormatException e) {
|
||||
throw new SydApiException(1005,e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String readBarCode(String filepath){
|
||||
// 加载二维码图像
|
||||
File BarCodeImage = new File(filepath);
|
||||
|
||||
try {
|
||||
// 读取条形码图像
|
||||
BufferedImage bufferedImage = ImageIO.read(BarCodeImage);
|
||||
|
||||
// 使用 ZXing 的 MultiFormatReader 进行解码
|
||||
MultiFormatReader reader = new MultiFormatReader();
|
||||
LuminanceSource source = new BufferedImageLuminanceSource(bufferedImage);
|
||||
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
|
||||
|
||||
// 解码条形码
|
||||
Result result = reader.decode(bitmap);
|
||||
|
||||
// 提取条形码中的数据
|
||||
return result.getText();
|
||||
} catch (NotFoundException e) {
|
||||
throw new SydApiException(1006,e);
|
||||
} catch (IOException e) {
|
||||
throw new SydApiException(1007,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.sunyard.RetWrap;
|
||||
import com.sunyard.SYMEnDeLongData;
|
||||
import com.sunyard.SydApi;
|
||||
import com.sunyard.SydApiException;
|
||||
import com.sunyard.cert.Cert;
|
||||
import com.sunyard.cert.X509;
|
||||
import com.sunyard.constant.CertUsage;
|
||||
import com.sunyard.entity.Struct;
|
||||
@@ -48,6 +49,7 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
import static com.sunyard.util.DnUtil.verifyDn;
|
||||
import static org.bouncycastle.asn1.ASN1Encoding.DL;
|
||||
|
||||
public class SydApi4j implements SydApi {
|
||||
|
||||
@@ -549,6 +551,87 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void QRCodeSign(String orgData, String sCertDN,String filepath) {
|
||||
byte[] sign = null;
|
||||
if (orgData == null) {
|
||||
throw new IllegalArgumentException("输入数据为 null");
|
||||
} else {
|
||||
sign = orgData.length() < 4096 ? this.SYD_NakedSign(sCertDN, orgData.getBytes(), (byte[])null) : this.SYD_NakedSign_OuterHash(orgData.getBytes(), sCertDN);
|
||||
}
|
||||
QRCodeUtil.genQRCode(orgData+"+"+Util.bytes2HexString(sign),filepath);
|
||||
}
|
||||
|
||||
|
||||
public void QRCodeSignRSA(int rFlag, String orgData, String sCertDN,String filepath) {
|
||||
byte[] sign = null;
|
||||
if (orgData == null) {
|
||||
throw new IllegalArgumentException("输入数据为 null");
|
||||
} else {
|
||||
sign = orgData.length() < 4096 ? this.SYD_NakedSign(rFlag,sCertDN, orgData.getBytes(), (byte[])null) : this.SYD_NakedSign_OuterHash(rFlag,orgData.getBytes(), sCertDN);
|
||||
}
|
||||
QRCodeUtil.genQRCode(orgData+"+"+Util.bytes2HexString(sign),filepath);
|
||||
|
||||
}
|
||||
|
||||
public boolean QRCodeVer( String sCertDN,String filepath) {
|
||||
String s = QRCodeUtil.readQRCode(filepath);
|
||||
String[] split = s.split("\\+");
|
||||
byte[] orgData = split[0].getBytes();
|
||||
byte[] sign = Util.hexString2Bytes(split[1]);
|
||||
return orgData.length < 4096 ? this.SYD_NakedVerify(sCertDN, sign, orgData, (byte[])null) : this.SYD_NakedVerify_OuterHash(orgData, sign, sCertDN);
|
||||
}
|
||||
|
||||
|
||||
public boolean QRCodeVerRSA( int rFlag,String sCertDN,String filepath) {
|
||||
String s = QRCodeUtil.readQRCode(filepath);
|
||||
String[] split = s.split("\\+");
|
||||
byte[] orgData = split[0].getBytes();
|
||||
byte[] sign = Util.hexString2Bytes(split[1]);
|
||||
return orgData.length < 4096 ? this.SYD_NakedVerify(rFlag,sCertDN, sign, orgData, (byte[])null) : this.SYD_NakedVerify_OuterHash(rFlag,orgData, sign, sCertDN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void BarCodeSign(String orgData, String sCertDN,String filepath) {
|
||||
byte[] sign = null;
|
||||
if (orgData == null) {
|
||||
throw new IllegalArgumentException("输入数据为 null");
|
||||
} else {
|
||||
sign = orgData.length() < 4096 ? this.SYD_NakedSign(sCertDN, orgData.getBytes(), (byte[])null) : this.SYD_NakedSign_OuterHash(orgData.getBytes(), sCertDN);
|
||||
}
|
||||
QRCodeUtil.genBarCode(orgData+"+"+Util.bytes2HexString(sign),filepath);
|
||||
}
|
||||
|
||||
|
||||
public void BarCodeSignRSA(int rFlag, String orgData, String sCertDN,String filepath) {
|
||||
byte[] sign = null;
|
||||
if (orgData == null) {
|
||||
throw new IllegalArgumentException("输入数据为 null");
|
||||
} else {
|
||||
sign = orgData.length() < 4096 ? this.SYD_NakedSign(rFlag,sCertDN, orgData.getBytes(), (byte[])null) : this.SYD_NakedSign_OuterHash(rFlag,orgData.getBytes(), sCertDN);
|
||||
}
|
||||
QRCodeUtil.genBarCode(orgData+"+"+Util.bytes2HexString(sign),filepath);
|
||||
|
||||
}
|
||||
|
||||
public boolean BarCodeVer( String sCertDN,String filepath) {
|
||||
String s = QRCodeUtil.readBarCode(filepath);
|
||||
String[] split = s.split("\\+");
|
||||
byte[] orgData = split[0].getBytes();
|
||||
byte[] sign = Util.hexString2Bytes(split[1]);
|
||||
return orgData.length < 4096 ? this.SYD_NakedVerify(sCertDN, sign, orgData, (byte[])null) : this.SYD_NakedVerify_OuterHash(orgData, sign, sCertDN);
|
||||
}
|
||||
|
||||
|
||||
public boolean BarCodeVerRSA( int rFlag,String sCertDN,String filepath) {
|
||||
String s = QRCodeUtil.readBarCode(filepath);
|
||||
String[] split = s.split("\\+");
|
||||
byte[] orgData = split[0].getBytes();
|
||||
byte[] sign = Util.hexString2Bytes(split[1]);
|
||||
return orgData.length < 4096 ? this.SYD_NakedVerify(rFlag,sCertDN, sign, orgData, (byte[])null) : this.SYD_NakedVerify_OuterHash(rFlag,orgData, sign, sCertDN);
|
||||
}
|
||||
|
||||
public byte[] SYD_NakedSign(String sCertDN, byte[] orgData, byte[] hash) {
|
||||
|
||||
Proto8003 proto = new Proto8003();
|
||||
@@ -1129,6 +1212,90 @@ public class SydApi4j implements SydApi {
|
||||
|
||||
}
|
||||
|
||||
public boolean detachedVerify(byte[] orgData, String sign){
|
||||
try {
|
||||
if( orgData.length<4096 ){
|
||||
return detachedVerify(DATA_ORIGIN,orgData,sign);
|
||||
}else {
|
||||
RetWrap retWrap = ASN1Util.takeOutOriginDataFromPKCS7Sign(sign);
|
||||
byte[] pk =(byte[]) retWrap.get("pk");
|
||||
byte[] hash = this.SM3Hash(Util.bytes2HexString(pk), orgData);
|
||||
return detachedVerify(DATA_HASH,hash,sign);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getCertBySign(String sign){
|
||||
RetWrap retWrap = null;
|
||||
try {
|
||||
retWrap = ASN1Util.takeOutOriginDataFromPKCS7Sign(sign);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String cert = (String) retWrap.get("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;
|
||||
}
|
||||
return pemCert;
|
||||
}
|
||||
|
||||
|
||||
public HashMap<String,String> getCertTime(String dn){
|
||||
String cert = null;
|
||||
try {
|
||||
cert = getCertByDn(dn);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
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 = null;
|
||||
try {
|
||||
certificate = CertUtil.convertToX509Cert(cert);
|
||||
} catch (Exception e) {
|
||||
throw new SydApiException( 0xC101, e );
|
||||
}
|
||||
|
||||
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyyMMdd");
|
||||
String afterDate = outputFormat.format(certificate.getNotAfter());
|
||||
String beforeDate = outputFormat.format(certificate.getNotBefore());
|
||||
|
||||
HashMap<String, String> hashMap = new HashMap<String, String>();
|
||||
hashMap.put("after",afterDate);
|
||||
hashMap.put("before",beforeDate);
|
||||
return hashMap;
|
||||
}
|
||||
|
||||
public String importCertAndGetDN(String cert){
|
||||
RetWrap retWrap = importCert(cert.getBytes(),null);
|
||||
String dn = null;
|
||||
int isImport= (Integer) retWrap.get("isImport");
|
||||
if(isImport == 0) {
|
||||
X509Certificate certificate = null;
|
||||
try {
|
||||
certificate = CertUtil.convertToX509Cert(cert);
|
||||
} catch (Exception e) {
|
||||
throw new SydApiException( 0xC101, e );
|
||||
}
|
||||
dn = certificate.getSubjectDN().toString();
|
||||
}
|
||||
return dn;
|
||||
}
|
||||
|
||||
public boolean attachedVerifyAll(int rFlag, String sign){
|
||||
try {
|
||||
boolean sm2Cert = CertUtil.isSignedBySM2Cert(sign);
|
||||
@@ -1381,6 +1548,23 @@ public class SydApi4j implements SydApi {
|
||||
|
||||
}
|
||||
|
||||
public String detachedSign(byte[] orgData, String sCertDN){
|
||||
try {
|
||||
if (orgData.length<4096){
|
||||
return detachedSign(DATA_ORIGIN,orgData,sCertDN);
|
||||
}else {
|
||||
String pk = null;
|
||||
pk = this.SYD_SM2_Get_Dn_PublicKey_HA(sCertDN.getBytes("GBK"), 0);
|
||||
System.out.println(pk);
|
||||
byte[] hash = this.SM3Hash(pk, orgData);
|
||||
System.out.println("hash为:"+Util.bytes2HexString(hash));
|
||||
return detachedSign(DATA_HASH,hash,sCertDN);
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String attachedSignAll(int rFlag,byte[] orgData, String sCertDN){
|
||||
try {
|
||||
String cert = getCertByDn(sCertDN,0);
|
||||
@@ -1772,6 +1956,43 @@ public class SydApi4j implements SydApi {
|
||||
return importCert(certData, organizationId, CertUsage.encipherOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String importCert(String certData) {
|
||||
Proto8009 proto = new Proto8009();
|
||||
// 填充数据
|
||||
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("certData", certData.getBytes());
|
||||
// 渲染发送
|
||||
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 CertUtil.getDN(certData);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean deleteCert(String dn) {
|
||||
Proto8011 proto = new Proto8011();
|
||||
@@ -1866,10 +2087,12 @@ public class SydApi4j implements SydApi {
|
||||
// System.out.println(s1);
|
||||
RetWrap r = new RetWrap();
|
||||
r.put("retCode", true);
|
||||
r.put("isImport", 0);
|
||||
|
||||
if ((0 != (be[0] ^ be[1]))) {
|
||||
|
||||
r.put("retCode", false);
|
||||
r.put("isImport", 1);
|
||||
r.put("msg", error.getInfo() == null || "".equals(error.getInfo()) ? RetWrap.transMsg(error.autoInt()) : error.getInfo());
|
||||
throw new SydApiException(error.getInfo(), error.autoInt());
|
||||
}
|
||||
@@ -3268,6 +3491,101 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RetWrap generateDEByDnICBC(String certSerial,String IV, byte[] oData,int roundmod ) {
|
||||
|
||||
// roundmod 轮模式,密钥加密模式:1=ECB,2=CBC
|
||||
|
||||
certSerial = 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 = SM2GenSessionKey(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;
|
||||
if(IV == null || IV.isEmpty()){
|
||||
String random = GenerateRandom(16);
|
||||
System.out.println("random:"+random);
|
||||
iv = random.getBytes();
|
||||
// Arrays.fill(iv, (byte) 0x30);
|
||||
}else{
|
||||
// if(32 != IV.getBytes().length){
|
||||
// throw new SydApiException("IV长度需为32位", 0x81);
|
||||
// }
|
||||
iv = IV.getBytes();
|
||||
}
|
||||
/**
|
||||
* E0 指令复合接口
|
||||
* @param isEn 指定加解密,true为加密,false为解密
|
||||
* @param nAlg 密钥模式,当isEn为true时,默认为SM4加密,0为DES加密,1为AES256 加密。当isEn为false时,默认为SM4解密,0为DES解密,1为AES256解密
|
||||
* @param seesionKey 密钥
|
||||
* @param roundmod 轮模式,密钥加密模式:1=ECB,2=CBC,3=CFB,4=OFB
|
||||
* @param fullMode 填充模式:0为饥饿模式,1为贪婪模式
|
||||
* @param pInData 消息数据
|
||||
* @param iv IV
|
||||
* @param block 消息块号
|
||||
* @return
|
||||
* iv: IV 数据域
|
||||
* msg_all: 消息数据
|
||||
*/
|
||||
|
||||
RetWrap retWrap = SYMEnDeData(true, 1, sessionKeyByLMK, roundmod, 1, oData, iv, 0);
|
||||
byte[] enData = (byte[]) retWrap.get("msg_all");
|
||||
// System.out.println("加密结果:"+Util.bytes2HexString(enData));
|
||||
|
||||
// 组织格式
|
||||
ContentInfo cms = genCMSEnvelopedData(Util.hexString2Bytes(ciperKey), enData,
|
||||
x509.getSerialNumber().toString(16),
|
||||
dnToMap(issuser.getName()),Util.hexString2Bytes(new String(iv))
|
||||
);
|
||||
// System.out.println("信封结果:"+Util.bytes2HexString(cms.getEncoded(DL)));
|
||||
|
||||
ret.put(SydApi.RET_CIPHER_KEY, Util.encodeBase64(cms.getEncoded(DL)));
|
||||
|
||||
return ret;
|
||||
|
||||
} catch (SydApiException syde) {
|
||||
throw syde;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new SydApiException("生成数字信封错误", -5);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RetWrap generateDEByDnRSA(int alg, String certSerial, byte[] oData) {
|
||||
if (oData.length <= 4 * 1024) {
|
||||
@@ -3819,6 +4137,51 @@ public class SydApi4j implements SydApi {
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
public static ContentInfo genCMSEnvelopedData(byte[] sessionKeyDer, byte[] enData, String sn, Map<String, String> issuer,byte[] iv) throws UnsupportedEncodingException {
|
||||
//String tmpl = "3082014D06092A864886F70D010703A082013E3082013A0201003181F73081F40201003065305C310B300906035504061302434E3130302E060355040A0C274368696E612046696E616E6369616C2043657274696669636174696F6E20417574686F72697479311B301906035504030C1243464341205445535420534D32204F43413102051004282452300B06092A811CCF5501822D03047B307902203C3AF535307DA548DA02C0AD171D2BC24D22472B42E5E175FCAF2C5CD30B5443022100ED53E7594F35FFACEB57F05898123F78E5B2D045CC47D894CD2E7BD34D66DA1D042014BD71F8CDA9729093A7CC391E2009C5D5F007586C2EBFB55BC175A6E8BDA33E04104AB82510BFDDD4FEE79C3F107D6F7F94303B060A2A811CCF550601040201301B06072A811CCF55016804100000000000000000000000000000000080109FD3D4338DB19E672CC162AF5B9B03E9";
|
||||
String tmpl = "3082014E060A2A811CCF550601040203A082013E3082013A0201003181F73081F40201003065305C310B300906035504061302434E3130302E060355040A0C274368696E612046696E616E6369616C2043657274696669636174696F6E20417574686F72697479311B301906035504030C1243464341205445535420534D32204F43413102051004282452300B06092A811CCF5501822D03047B307902203C3AF535307DA548DA02C0AD171D2BC24D22472B42E5E175FCAF2C5CD30B5443022100ED53E7594F35FFACEB57F05898123F78E5B2D045CC47D894CD2E7BD34D66DA1D042014BD71F8CDA9729093A7CC391E2009C5D5F007586C2EBFB55BC175A6E8BDA33E04104AB82510BFDDD4FEE79C3F107D6F7F94303B060A2A811CCF550601040201301B06072A811CCF55016804100000000000000000000000000000000080109FD3D4338DB19E672CC162AF5B9B03E9";
|
||||
ContentInfo info = SydCmsUtil.getContentInfo(Util.hexString2Bytes(tmpl));
|
||||
// 修改
|
||||
ASN1Sequence seq = (ASN1Sequence) info.getContent().toASN1Primitive();
|
||||
|
||||
ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(1).toASN1Primitive());
|
||||
ASN1Sequence seq2 = (ASN1Sequence) set.getObjectAt(0).toASN1Primitive();
|
||||
|
||||
// 会话密钥
|
||||
DEROctetString key = (DEROctetString) seq2.getObjectAt(3);
|
||||
BeanUtil.setFieldValue(key, "string", sessionKeyDer);
|
||||
|
||||
// 签发信息段
|
||||
ASN1Sequence seq3 = (ASN1Sequence) seq2.getObjectAt(1).toASN1Primitive();
|
||||
ASN1Integer isn = (ASN1Integer) seq3.getObjectAt(1).toASN1Primitive();
|
||||
BeanUtil.setFieldValue(isn, "bytes", Util.hexString2Bytes(sn));
|
||||
|
||||
ASN1Sequence seq4 = (ASN1Sequence) seq3.getObjectAt(0).toASN1Primitive();
|
||||
ASN1Set setO = (ASN1Set) seq4.getObjectAt(1).toASN1Primitive();
|
||||
ASN1Sequence seqO = (ASN1Sequence) setO.getObjectAt(0).toASN1Primitive();
|
||||
DERUTF8String o = (DERUTF8String) seqO.getObjectAt(1).toASN1Primitive();
|
||||
BeanUtil.setFieldValue(o, "string", issuer.get("O").getBytes("UTF-8"));
|
||||
|
||||
ASN1Set setCN = (ASN1Set) seq4.getObjectAt(2).toASN1Primitive();
|
||||
ASN1Sequence seqCn = (ASN1Sequence) setCN.getObjectAt(0).toASN1Primitive();
|
||||
DERUTF8String Cn = (DERUTF8String) seqCn.getObjectAt(1).toASN1Primitive();
|
||||
BeanUtil.setFieldValue(Cn, "string", issuer.get("CN").getBytes("UTF-8"));
|
||||
|
||||
// 密文段
|
||||
ASN1Sequence seq5 = (ASN1Sequence) seq.getObjectAt(2).toASN1Primitive();
|
||||
ASN1TaggedObject tag = (ASN1TaggedObject) seq5.getObjectAt(2).toASN1Primitive();
|
||||
DEROctetString data = (DEROctetString) tag.getObject();
|
||||
BeanUtil.setFieldValue(data, "string", enData);
|
||||
|
||||
//iv段
|
||||
ASN1Sequence seq6 = (ASN1Sequence)seq5.getObjectAt(1).toASN1Primitive();
|
||||
DEROctetString ivtag = (DEROctetString) seq6.getObjectAt(1).toASN1Primitive();
|
||||
BeanUtil.setFieldValue(ivtag, "string", iv);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public static ContentInfo genCMSEnvelopedDataRSA(byte[] sessionKeyDer, byte[] enData, String sn, Map<String, String> issuer) throws UnsupportedEncodingException {
|
||||
String tmpl = "308201d506092a864886f70d010703a08201c6308201c20201003182017c3082017802010030623059310b300906035504061302434e3130302e060355040a13274368696e612046696e616e6369616c2043657274696669636174696f6e20417574686f72697479311830160603550403130f434643412054455354204f4341313102052003470933300b06092a864886f70d01010104820100e0f8d8cf94321e7b41452845e98d5998d8c0af8aaf63a5c67a05c27c82eac3f7251d0374e59a53af39898de43a6ed9e8ca642cf3b9d19be7529be767491452b990938199384f5f7f244055ed6472e29fec18103f868109cde28f40641ddaa3c408d0629c05ec8f34b1d629975f03e05734c9931f4eae9fce912a0f8e7f726b02f3696b31c6155c191b245c8ebbb381da6f19a0b5e00e3006a3084f6519874c871ae054eae1f723aaf20982d78864b72153e47960e606cc448ece1f75a8a2f08aab2b8773af1569089253c46b7c4deab20d47a671a7f5bf06546087b98885507b69bd186c73a658efbcdd2edd5b55ea515c38729dd386425132cd5a95b5cd8e2d303d060a2a811ccf550601040201301d060960864801650304012a041000000000000000000000000000000000801043cfb263acadf7f0a5071fd7f94282ab";
|
||||
ContentInfo info = SydCmsUtil.getContentInfo(Util.hexString2Bytes(tmpl));
|
||||
@@ -3866,6 +4229,47 @@ public class SydApi4j implements SydApi {
|
||||
}
|
||||
}
|
||||
|
||||
public RetWrap decryptDEByDNICBC(String certSerial, String IV,String pCipherKey,int roundmod) {
|
||||
|
||||
certSerial = 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 = Util.bytes2HexString((byte[]) ret.get("iv")).getBytes(); //new byte[32];
|
||||
System.out.println("实际iv值hex:"+Util.bytes2HexString((byte[]) ret.get("iv")));
|
||||
if(null != IV && !IV.isEmpty()){
|
||||
iv = IV.getBytes();
|
||||
}
|
||||
// 解密会话密钥
|
||||
ret = decryptDE(false, 1, dnBytes, Util.encodeBase64(sessionKeyDer));
|
||||
String sessionKey = new String((byte[]) ret.get("SessionKey"));
|
||||
|
||||
RetWrap retWrap = SYMEnDeData(false, 1, sessionKey, roundmod, 1, enData, iv, 0);
|
||||
byte[] data = (byte[]) retWrap.get("msg_all");
|
||||
|
||||
ret.put("oData", data);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public RetWrap decryptDEByDNRSA(int alg, String certSerial, byte[] pCipherKey) {
|
||||
if (pCipherKey.length <= 4 * 1024) {
|
||||
|
||||
Reference in New Issue
Block a user