171 lines
5.9 KiB
Java
171 lines
5.9 KiB
Java
package com.sunyard.util;
|
|
|
|
import cn.hutool.core.codec.Base64;
|
|
import com.sunyard.RetWrap;
|
|
import com.sunyard.SydApiException;
|
|
import com.sunyard.constant.CertUsage;
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import sun.misc.BASE64Encoder;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.IOException;
|
|
import java.security.NoSuchProviderException;
|
|
import java.security.Security;
|
|
import java.security.cert.CertificateEncodingException;
|
|
import java.security.cert.CertificateException;
|
|
import java.security.cert.CertificateFactory;
|
|
import java.security.cert.X509Certificate;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
|
|
public class CertUtil {
|
|
public static String encodeBase64(byte[] data) {
|
|
return new BASE64Encoder().encode(data);
|
|
}
|
|
|
|
static {
|
|
Security.addProvider(new BouncyCastleProvider());
|
|
}
|
|
|
|
public static X509Certificate convertToX509Cert(String certificateString) throws CertificateException, NoSuchProviderException {
|
|
// X509Certificate certificate = null;
|
|
// CertificateFactory cf = null;
|
|
// try {
|
|
// if (certificateString != null && !certificateString.trim().isEmpty()) {
|
|
// certificateString = certificateString.replace("-----BEGIN CERTIFICATE-----\n", "")
|
|
// .replace("-----END CERTIFICATE-----", ""); // NEED FOR PEM FORMAT CERT STRING
|
|
// byte[] certificateData = Base64.decode(certificateString);
|
|
// cf = CertificateFactory.getInstance("X509");
|
|
// certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certificateData));
|
|
// }
|
|
// } catch (CertificateException e) {
|
|
// throw new CertificateException(e);
|
|
// }
|
|
// return certificate;
|
|
CertificateFactory CF = CertificateFactory.getInstance("X.509", "BC"); // 从证书工厂中获取X.509的单例类
|
|
return (X509Certificate) CF.generateCertificate(new ByteArrayInputStream(certificateString.getBytes())); // 将文件流的证书转化为证书类
|
|
}
|
|
|
|
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.getBytes();
|
|
String pemCertPre = new String(Base64.encode(derCert, true));
|
|
String pemCert = cert_begin + pemCertPre + end_cert;
|
|
return pemCert;
|
|
// StringWriter sw = new StringWriter();
|
|
// PemWriter pw = new PemWriter(sw);
|
|
// try {
|
|
// pw.writeObject(new JcaMiscPEMGenerator(cert));
|
|
// }catch ( Exception e ) {
|
|
// e.printStackTrace();
|
|
// }finally {
|
|
// if (null == pw) {
|
|
// try {
|
|
// pw.close();
|
|
// } catch (IOException e) {
|
|
// e.printStackTrace();
|
|
// }
|
|
// }
|
|
// }
|
|
// return sw.toString();
|
|
}
|
|
|
|
/**
|
|
* 判断正式是否是国密证书
|
|
*
|
|
* @param cert 证书 base64 字符
|
|
* @return true 国密, false 非国密
|
|
*/
|
|
public static boolean isSM2Cert(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 );
|
|
}
|
|
String signAlg = certificate.getSigAlgName();
|
|
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 是否是国密证书签的
|
|
*
|
|
* @param pkcs7 pkcs7
|
|
* @return true 国密, false 非国密
|
|
*/
|
|
public static boolean isSignedBySM2Cert(String pkcs7) throws IOException, CertificateException, NoSuchProviderException {
|
|
RetWrap ret = ASN1Util.takeOutOriginDataFromPKCS7Sign(pkcs7);
|
|
//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);
|
|
}
|
|
}
|
|
|
|
|
|
public static boolean certUsageCheck(String cert , CertUsage... us ) throws CertificateException, NoSuchProviderException {
|
|
if ( null == us || us.length == 0) {
|
|
return true;
|
|
}
|
|
|
|
X509Certificate certificate = convertToX509Cert(cert);
|
|
boolean[] usage = certificate.getKeyUsage();
|
|
|
|
if ( null == usage ) {
|
|
return false;
|
|
}
|
|
|
|
boolean checkRet = true;
|
|
Set<Integer> uset = new HashSet<Integer>();
|
|
for ( CertUsage u : us ) {
|
|
uset.add( u.ordinal() );
|
|
}
|
|
|
|
for ( int i = 0; i < usage.length; i++ ) {
|
|
if ( usage[ i ] ) {
|
|
checkRet &= uset.contains( i );
|
|
}
|
|
}
|
|
|
|
return checkRet;
|
|
}
|
|
|
|
}
|