基于BouncyCastle的证书格式转换demo编写

基于BouncyCastle的证书格式转换demo编写

任务清单

  • der->pem;
  • pem->der;
  • pfx->jks;
  • jks->pfx;
  • asn.1解析。
  • 前置需求:配置BouncyCastle

(1)der->pem

  • 主要需要的包:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import java.security.cert.CertificateFactory;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
  • 代码:
package BC;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;

import java.io.*;

import java.security.cert.CertificateFactory;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;

public class DerToPem {
    public  static X509Certificate getDerCert(String path) throws IOException, CertificateException, NoSuchProviderException {
        //加载BC
        Security.addProvider( new BouncyCastleProvider() );

        //读DER证书
        File file = new File(path);
        long filesize = file.length();
        FileInputStream fis = new FileInputStream(file);
        byte[] cert = new byte[(int) filesize];
        int offset = 0;
        int numRead = 0;
        while (offset < cert.length && (numRead = fis.read(cert, offset, cert.length - offset)) >= 0) {
            offset += numRead;
        }
        fis.close();

        //输出X509格式证书
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509","BC");//使用BC获取工厂实例
        Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(cert));//用文件流读入证书
        X509Certificate x509Certificate = (X509Certificate)certificate;//强转
        return x509Certificate;
    }

    public static void writePemCert(String path, X509Certificate x509Certificate) throws IOException, CertificateEncodingException {
        //加载BC
        Security.addProvider( new BouncyCastleProvider() );

        //BC转化PEM格式证书
        StringWriter str = new StringWriter();
        PemWriter pemWriter = new PemWriter(str);
        pemWriter.writeObject(new PemObject("CERTIFICATE",x509Certificate.getEncoded()));//使用BC提供的PemWriter写入证书
        pemWriter.close();
        str.close();
        FileOutputStream fos;
        fos = new FileOutputStream(path);
        fos.write(str.toString().getBytes());
        System.out.println("Successful!");
    }

    public static void main(String[] args) throws Exception {
        //调用demo
        String pathSrc = "lzc_cert_demo.der";
        String pathDst = "lzc_cert_demo.pem";
        String s = pathSrc.substring(pathSrc.length() - 3);
        /*if (!((s.equals("pem")) || (s.equals("crt")) || (s.equals("cer")))) {
            System.out.println("输入错误!");
            System.exit(-1);
        }*/
        X509Certificate certificate  = DerToPem.getDerCert(pathSrc);
        DerToPem.writePemCert(pathDst,certificate);
    }

}

(2)pem->der

  • 1.主要需要的包:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import java.security.cert.CertificateFactory;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
  • 2.代码:
package BC;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import java.io.*;

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.Certificate;
import java.security.cert.X509Certificate;

public class PemToDer {
    public  static X509Certificate getPemCert(String path) throws IOException, CertificateException, NoSuchProviderException {
        //加载BC
        Security.addProvider( new BouncyCastleProvider() );

        //使用BC提供的PemReader读取证书
        PemReader pemReader = new PemReader( new FileReader(path) );
        PemObject pemObject = pemReader.readPemObject();
        byte cert[] = pemObject.getContent();

        //输出X509格式证书
        InputStream inStream = new ByteArrayInputStream(cert);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");//使用BC获取工厂实例
        Certificate certificate = certificateFactory.generateCertificate(inStream);//用文件流读入证书
        X509Certificate x509Certificate = (X509Certificate)certificate;
        return x509Certificate;
    }

    public static void writeDerCert(String path, X509Certificate x509Certificate) throws IOException, CertificateEncodingException {
        //输出DER格式证书
        byte[] cert = x509Certificate.getEncoded();
        File file=new File(path);
        if(!file.exists()){
            file.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(cert);
        fos.close();
        System.out.println("Successful!");
    }
    public static void main(String[] args) throws Exception {
        String pathSrc = "lzc_cert_demo.pem";
        String pathDst = "lzc_cert_demo.der";
        String s = pathSrc.substring(pathSrc.length() - 3);
        /*if (!((s.equals("pem")) || (s.equals("crt")) || (s.equals("cer")))) {
                System.out.println("输入错误!");
                System.exit(-1);
        }*/
        X509Certificate certificate  = PemToDer.getPemCert(pathSrc);
        PemToDer.writeDerCert(pathDst,certificate);
    }

}

(3)pfx->jks

  • 1.主要需要的包:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.cert.Certificate;
import java.security.*;
  • 2.代码:
package BC;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.Certificate;
import java.util.Enumeration;

public class PfxToJks {
    public static void ToJKS(String pathSrc, String pathDst, char[] passwd) throws IOException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException, UnrecoverableKeyException {
        //读PFX证书,用密钥解密证书
        Security.addProvider(new BouncyCastleProvider());
        FileInputStream fs = new FileInputStream(pathSrc);
        KeyStore store = KeyStore.getInstance("PKCS12", "BC");//使用BC初始化KeyStore
        store.load(fs, passwd);//从给定的输入流加载密钥库
        fs.close();

        KeyStore outputKeyStore = KeyStore.getInstance("JKS");//BC不提供对于JKS的KeyStore,直接初始化KeyStore
        outputKeyStore.load(null, passwd);

        //证书写入
        Enumeration<String> enumas = store.aliases();
        while (enumas.hasMoreElements()) {
            String keyAlias = (String) enumas.nextElement();
            System.out.println("alias=[" + keyAlias + "]");
            if (store.isKeyEntry(keyAlias)) {
                Key key = store.getKey(keyAlias, passwd);//获取私钥
                Certificate[] certChain = store.getCertificateChain(keyAlias);
                outputKeyStore.setKeyEntry(keyAlias, key, passwd, certChain);
            }
        }
        FileOutputStream out = new FileOutputStream(pathDst);
        outputKeyStore.store(out, passwd);
        out.close();
    }

    public static void main(String[] args) throws CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException, KeyStoreException, UnrecoverableKeyException {
        String pathSrc = "rsa.lzc.pfx";
        String pathDst = "rsa.lzc.jks";
        String passwd = "12345678";

        PfxToJks.ToJKS(pathSrc, pathDst, passwd.toCharArray());
    }
}

(4)jks->pfx

  • 1.主要需要的包:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.cert.Certificate;
import java.security.*;
  • 2.代码:
package BC;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.Certificate;
import java.util.Enumeration;

public class JksToPfx {
    public static void ToPFX(String pathSrc, String pathDst, char[] passwd) throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, UnrecoverableKeyException {
        //读JKS证书,用密钥解密证书
        Security.addProvider(new BouncyCastleProvider());
        FileInputStream fs = new FileInputStream(pathSrc);
        KeyStore store = KeyStore.getInstance("JKS");//BC不提供对于JKS的KeyStore,直接初始化KeyStore
        store.load(fs, passwd);//从给定的输入流加载密钥库
        fs.close();

        KeyStore outputKeyStore = KeyStore.getInstance("PKCS12", "BC");//使用BC初始化KeyStore
        outputKeyStore.load(null, passwd);

        //证书写入
        Enumeration<String> enums = store.aliases();
        while (enums.hasMoreElements()) {
            String keyAlias = (String) enums.nextElement();
            //System.out.println("alias=[" + keyAlias + "]");
            if (store.isKeyEntry(keyAlias)) {
                Key key = store.getKey(keyAlias, passwd);//获取私钥
                Certificate[] certChain = store.getCertificateChain(keyAlias);
                outputKeyStore.setKeyEntry(keyAlias, key, passwd, certChain);
            }
        }
        FileOutputStream out = new FileOutputStream(pathDst);
        outputKeyStore.store(out, passwd);
        out.close();
    }

    public static void main(String[] args) throws CertificateException, NoSuchAlgorithmException, IOException, NoSuchProviderException, KeyStoreException, UnrecoverableKeyException {
        String pathSrc = "rsa.lzc.jks";
        String pathDst = "rsa.lzc.pfx";
        String passwd = "12345678";

        JksToPfx.ToPFX(pathSrc, pathDst, passwd.toCharArray());
    }
}

(5)asn1解析

  • 1.主要需要的包:
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.util.ASN1Dump;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
  • 2.代码:
package BC;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.security.Security;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.util.ASN1Dump;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class asn1read {
    public static String asn1(String path) {
        //加载BC
        Security.addProvider(new BouncyCastleProvider());

        //加载文件
        File file = new File(path);
        String output = outputFilename(path);
        File txt = new File(output);
        if (txt.exists()) {
            txt.delete();
        }
        FileInputStream fileInputStream;
        try {
            fileInputStream = new FileInputStream(file);
            ASN1InputStream aSN1InputStream = new ASN1InputStream(fileInputStream);//创建一个ASN1InputStream对象
            ASN1Primitive aSN1Primitive;
            while ((aSN1Primitive = aSN1InputStream.readObject()) != null) { //读取
                String re = ASN1Dump.dumpAsString(aSN1Primitive);//调用BC提供的ASN1Dump解析并输出字符串
                FileWriter writer = new FileWriter(output, true);//写入文件
                writer.write(re);
                writer.close();
                System.out.println(re);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return output;

    }

    public static String outputFilename(String path) {
        String filename = "";
        int length = path.length();
        int i;
        for (i = length - 1; i >= 0; i--) {
            if (path.charAt(i) == '.') {
                filename = path.substring(0, i + 1);
                break;
            }
        }
        filename = filename + "txt";
        return filename;
    }

    public static void main(String[] args) {
        String path = "sm2.lzc.enc.crt.pem";
        System.out.println("解析文件保存为:" + asn1(path));
    }
}

posted @ 2021-03-31 10:14  20175214lzc  阅读(1758)  评论(0编辑  收藏  举报