package com.nova.sankuai.domain.api.yinsheng;
|
|
import cfca.sadk.algorithm.common.Mechanism;
|
import cfca.sadk.algorithm.sm2.SM2PublicKey;
|
import cfca.sadk.lib.crypto.JCrypto;
|
import cfca.sadk.lib.crypto.Session;
|
import cfca.sadk.util.EnvelopeUtil;
|
import cfca.sadk.util.KeyUtil;
|
import cfca.sadk.util.Signature;
|
import cfca.sadk.x509.certificate.X509Cert;
|
|
import java.security.PrivateKey;
|
|
|
/**
|
* @类名称:GMSignUtil
|
* @类描述:国密算法SM2签名工具类
|
*/
|
public class GMSignUtils {
|
|
/**
|
* 获取支付平台公钥证书
|
* @param src
|
* @return
|
* @throws Exception
|
*/
|
public static GMCertInfo getVerifyCertInfo(String src) throws Exception {
|
GMCertInfo certInfo = new GMCertInfo();
|
try{
|
certInfo.ReadPublicKeyFromX509CertificateSM2(src);
|
} catch (Exception e) {
|
throw new Exception("银盛平台公钥证书加载失败");
|
}
|
return certInfo;
|
}
|
|
|
/**
|
* 国密算法验证签名(报文)
|
* @param certInfo
|
* @param bcheck
|
* @param xmlMsg
|
* @throws Exception
|
*/
|
public static boolean verifyMsgSignSM2(GMCertInfo certInfo, byte[] bcheck, byte[] xmlMsg){
|
boolean bFlag;
|
try{
|
SM2PublicKey pubKey = certInfo.getPubKeySM2();
|
final String deviceName = JCrypto.JSOFT_LIB;
|
JCrypto.getInstance().initialize(deviceName, null);
|
Session session = JCrypto.getInstance().openSession(deviceName);
|
final Signature util = new Signature();
|
final String signAlg = Mechanism.SM3_SM2;//SM3WithSM2
|
// 校验,必须指定签名算法
|
bFlag = util.p1VerifyMessage(signAlg,xmlMsg,bcheck,pubKey,session);
|
} catch (Exception e) {
|
bFlag = false;
|
System.out.println("国密验签失败"+e);
|
}
|
return bFlag;
|
}
|
|
/**
|
* 获取商户私钥证书
|
* @param src
|
* @return
|
* @throws Exception
|
*/
|
public synchronized static GMCertInfo getSignCertInfo(String src) throws Exception {
|
//商户私钥证书
|
String certfile = src;
|
System.out.println("证书路经---"+certfile);
|
GMCertInfo certInfo = new GMCertInfo();
|
try {
|
byte[] priKeySm2 = TextFileHelper.readFile(certfile);
|
certInfo.setPriKey(priKeySm2);
|
} catch (Exception e) {
|
throw new Exception("商户签名证书加载失败");
|
}
|
|
return certInfo;
|
}
|
|
/**
|
* 国密算法签名(报文)
|
* @param sm2FilePath
|
* @param msg
|
* @return 返回 256长度base64编码
|
* @throws Exception
|
*/
|
public synchronized static String signMsgSM2(String sm2FilePath,String passWord, String msg) throws Exception {
|
GMCertInfo certInfo = getSignCertInfo(sm2FilePath);
|
// 返回的是256位
|
byte[] signed;
|
try {
|
final String deviceName = JCrypto.JSOFT_LIB;
|
JCrypto.getInstance().initialize(deviceName, null);
|
Session session = JCrypto.getInstance().openSession(deviceName);
|
PrivateKey priKey = KeyUtil.getPrivateKeyFromSM2(certInfo.getPriKey(),passWord);
|
// PrivateKey priKey = KeyUtil.getPrivateKeyFromSM2(certInfo.getPriKey(),"ys123456");
|
byte[] sourceData = msg.getBytes();
|
Signature util = new Signature();
|
String signAlg = Mechanism.SM3_SM2;//SM3WithSM2
|
// 签名,必须指定签名算法,返回BASE64签名结果
|
signed = util.p1SignMessage(signAlg, sourceData, priKey, session);
|
} catch (Exception e) {
|
e.printStackTrace();
|
throw new Exception("报文SM2签名失败");
|
}
|
String checkValue = new String(signed);
|
return String.format("%-256s", checkValue);
|
}
|
|
/**
|
* 国密算法数据加密(SM2公钥加密:长度通常限定为136字节内)
|
* @param src
|
* @param data
|
* @throws Exception
|
*/
|
public static String encryptData(String src,String data) throws Exception {
|
String encryptMsg = null;
|
GMCertInfo certInfo = getVerifyCertInfo(src);
|
try {
|
final String deviceName = JCrypto.JSOFT_LIB;
|
JCrypto.getInstance().initialize(deviceName, null);
|
final Session session = JCrypto.getInstance().openSession(deviceName);
|
// 一个或者多个加密证书
|
X509Cert[] recvcerts = new X509Cert[] { certInfo.getX509Cert() };
|
byte[] base64Bytes = EnvelopeUtil.envelopeMessage(data.getBytes("UTF-8"), Mechanism.SM4_ECB, recvcerts, session);
|
encryptMsg = new String(base64Bytes);
|
} catch (Exception e) {
|
throw new Exception("数据SM2加密失败");
|
}
|
return encryptMsg;
|
}
|
|
}
|