java bouncycastle生成数字证书工具类

需要引入的jar包

<dependency>
	<groupId>org.bouncycastle</groupId>
	<artifactId>bcprov-jdk15to18</artifactId>
	<version>1.69</version>
</dependency>
<dependency>
	<groupId>org.bouncycastle</groupId>
	<artifactId>bcpkix-jdk15to18</artifactId>
	<version>1.69</version>
</dependency>
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.util.io.pem.PemObject;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Date;

public class CertificateUtil {
    public static final String SUBJECT="C=CN,ST=HB,L=WH,O=HK,OU=CA,CN=";
    public static final String ISSUER="C=CN,ST=HB,L=WH,O=HK,OU=CA,CN=CA";

    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    /**
     * 读取base64证书
     * @param cer
     * @return
     * @throws CertificateException
     */
    public static X509Certificate readCert(String cer) throws CertificateException, IOException {
        CertificateFactory certificate_factory = CertificateFactory.getInstance("X.509");
        try(InputStream inputStream = new ByteArrayInputStream(Base64.getDecoder().decode(cer))){
            X509Certificate x509certificate = (X509Certificate) certificate_factory.generateCertificate(inputStream);
            return x509certificate;
        }
    }

    //Generate version 3 X509Certificate
    public static X509Certificate generateV3SelfSignedCertificate(Date startDate, Date endDate, PrivateKey rootPrik, PublicKey rootPubk, PublicKey pubk, String issuer, String subject) {
        try {
            X500Name issuerDN = new X500Name(issuer);
            X500Name subjectDN = new X500Name(subject);
            BigInteger serialNumber = BigInteger.valueOf(startDate.getTime());


            SubjectPublicKeyInfo subPubKeyInfo = SubjectPublicKeyInfo.getInstance(pubk.getEncoded());
            //证书对象构建
            X509v3CertificateBuilder builder = new X509v3CertificateBuilder(issuerDN, serialNumber, startDate,
                    endDate, subjectDN, subPubKeyInfo);
            /*JcaX509ExtensionUtils extensionUtils = new JcaX509ExtensionUtils();
            GeneralName generalName = new GeneralName(GeneralName.dNSName,"www.111111.com");
            GeneralName generalName2 = new GeneralName(GeneralName.iPAddress,"111.111.111.111");
            GeneralNames generalNames = new GeneralNames(new GeneralName[]{generalName,generalName2});
            DistributionPointName distributionPoint =new DistributionPointName(generalNames);
            DistributionPoint[] points = new DistributionPoint[1];
            points[0] = new DistributionPoint(distributionPoint,null,null);
            CRLDistPoint crlDistPoint = new CRLDistPoint(points);*/
            /*builder.addExtension(Extension.subjectAlternativeName,false,generalNames);
            builder.addExtension(Extension.authorityKeyIdentifier,false, extensionUtils.createAuthorityKeyIdentifier(rootPubk));
            builder.addExtension(Extension.subjectKeyIdentifier,false,extensionUtils.createAuthorityKeyIdentifier(pubk));*/
            //证书完成数字签名
            X509CertificateHolder holder = builder.build(createSigner(rootPrik));
            return new JcaX509CertificateConverter().getCertificate(holder);
        } catch (Exception e) {
            throw new RuntimeException("Error creating X509v3Certificate.", e);
        }
    }

    /**
     * 创建前面对象
     * @param privKey
     * @return
     * @throws OperatorCreationException
     */
    public static ContentSigner createSigner(PrivateKey privKey) throws OperatorCreationException {
        return   new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(privKey);
    }
    /**
     * 证书转换为PEM格式数字证书
     */
    public static String convertToPem(X509Certificate x509Certificate) throws IOException, CertificateEncodingException {
        try(StringWriter str = new StringWriter();
            JcaPEMWriter pemWriter = new JcaPEMWriter(str)) {
            PemObject pemObject = new PemObject("RSA CERTIFICATE",x509Certificate.getEncoded());
            pemWriter.writeObject(pemObject);
            pemWriter.flush();
            return str.toString();
        }
    }
    /**
     * 证书转换为pfx格式证书,将结果集放到txt文件 扩展名pfx就可用于spring boot中作为https证书
     */
    public static String convertToPfx(PrivateKey privateKey,X509Certificate[] x509Certificate) throws IOException,NoSuchProviderException,KeyStoreException,CertificateException,NoSuchAlgorithmException{
        try(ByteArrayOutputStream fos = new ByteArrayOutputStream();){
            KeyStore keyStore = KeyStore.getInstance("PKCS12","BC");
            keyStore.load(null,null);
            keyStore.setKeyEntry("123",privateKey,"123".toCharArray(),x509Certificate);
            keyStore.store(fos,"123".toCharArray());
            fos.flush();
            return Base64.getEncoder().encodeToString(fos.toByteArray());
        }
    }

    /**
     * 双向ssl需要客户端配置证书和ca证书
     * @param caCert
     * @param cert
     * @param privateKey
     * @param password
     * @return
     * @throws KeyStoreException
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws IOException
     * @throws UnrecoverableKeyException
     * @throws KeyManagementException
     */
    public static SSLSocketFactory getSocketFactory(X509Certificate caCert,
                                                    X509Certificate cert, 
                                                    PrivateKey privateKey, 
                                                    String password) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException {

        // CA certificate is used to authenticate server
        KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
        caKs.load(null, null);
        caKs.setCertificateEntry("ca-certificate", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
        tmf.init(caKs);

        // client key and certificates are sent to server so it can authenticate
        // us
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        // ks.setCertificateEntry("certificate", cert);
        ks.setKeyEntry("private-key", privateKey, password.toCharArray(),
                new java.security.cert.Certificate[] { cert });
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
                .getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());

        // finally, create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1.2");
//        SSLContext context = SSLContext.getInstance("SSL");
        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
        return context.getSocketFactory();
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值