com.aqnote.shared.cryptology.cert.io.PKCSWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.aqnote.shared.cryptology.cert.io.PKCSWriter.java

Source

/*
 * Copyright 2013-2023 "Peng Li"<aqnote@qq.com> Licensed under the AQNote License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy of the License at
 * http://www.aqnote.com/licenses/LICENSE-1.0 Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and limitations under the
 * License.
 */
package com.aqnote.shared.cryptology.cert.io;

import static org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC;
import static org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder;
import org.bouncycastle.operator.OutputEncryptor;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS12PfxPdu;
import org.bouncycastle.pkcs.PKCS12PfxPduBuilder;
import org.bouncycastle.pkcs.PKCS12SafeBag;
import org.bouncycastle.pkcs.PKCS12SafeBagBuilder;
import org.bouncycastle.pkcs.bc.BcPKCS12MacCalculatorBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS12SafeBagBuilder;
import org.bouncycastle.pkcs.jcajce.JcePKCSPBEOutputEncryptorBuilder;

import com.aqnote.shared.cryptology.cert.constant.BCConstant;
import com.aqnote.shared.cryptology.cert.util.CertificateUtil;

/**
 * PKCSWriter.java????
 * 
 * @author "Peng Li"<aqnote@qq.com> Dec 6, 2013 7:24:53 PM
 */
public class PKCSWriter implements BCConstant {

    public static void storePKCS12File(X509Certificate[] chain, PrivateKey key, char[] pwd, OutputStream ostream)
            throws Exception {
        if (chain == null || key == null || ostream == null)
            return;

        PKCS12SafeBag[] certSafeBags = new PKCS12SafeBag[chain.length];
        for (int i = chain.length - 1; i > 0; i--) {
            PKCS12SafeBagBuilder safeBagBuilder = new JcaPKCS12SafeBagBuilder(chain[i]);
            safeBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute,
                    new DERBMPString(CertificateUtil.getSubjectCN(chain[i])));
            certSafeBags[i] = safeBagBuilder.build();
        }

        X509Certificate cert = chain[0];
        String subjectCN = CertificateUtil.getSubjectCN(cert);
        SubjectKeyIdentifier pubKeyId = new JcaX509ExtensionUtils().createSubjectKeyIdentifier(cert.getPublicKey());

        PKCS12SafeBagBuilder safeBagBuilder = new JcaPKCS12SafeBagBuilder(cert);
        safeBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString(subjectCN));
        safeBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute, pubKeyId);
        certSafeBags[0] = safeBagBuilder.build();

        PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder();
        // desEDE/id_aes256_CBC
        OutputEncryptor oKeyEncryptor = new JcePKCSPBEOutputEncryptorBuilder(pbeWithSHAAnd3_KeyTripleDES_CBC)
                .setProvider(JCE_PROVIDER).build(pwd);
        PKCS12SafeBagBuilder keySafeBagBuilder = new JcaPKCS12SafeBagBuilder(key, oKeyEncryptor);
        keySafeBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString(subjectCN));
        keySafeBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute, pubKeyId);
        pfxPduBuilder.addData(keySafeBagBuilder.build());

        OutputEncryptor oCertEncryptor = new JcePKCSPBEOutputEncryptorBuilder(pbeWithSHAAnd40BitRC2_CBC)
                .setProvider(JCE_PROVIDER).build(pwd);
        pfxPduBuilder.addEncryptedData(oCertEncryptor, certSafeBags);

        // PKCS12PfxPdu pfxPdu = pfxPduBuilder.build(new JcePKCS12MacCalculatorBuilder(idSHA1), pwd);
        BcPKCS12MacCalculatorBuilder builder = new BcPKCS12MacCalculatorBuilder(new SHA1Digest(),
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE));
        PKCS12PfxPdu pfxPdu = pfxPduBuilder.build(builder, pwd);

        ostream.write(pfxPdu.getEncoded(ASN1Encoding.DER));
        ostream.close();
    }

    public static void storePKCS12File(PKCS12PfxPdu pfxPdu, OutputStream ostream) throws Exception {
        if (pfxPdu == null || ostream == null)
            return;

        ostream.write(pfxPdu.getEncoded(ASN1Encoding.DER));
        ostream.close();
    }

    public static void storePKCS7File(X509Certificate cert, OutputStream ostream) throws Exception {
        // storePem(cert, ostream, null);
    }

    public static void storePKCS10File(PKCS10CertificationRequest csr, OutputStream ostream) throws Exception {
        StringBuilder csrString = new StringBuilder(CSR_BEGIN + _N);
        csrString.append(Base64.encodeBase64String(csr.getEncoded()) + _N);
        csrString.append(CSR_END);
        ostream.write(csrString.toString().getBytes());
        ostream.close();
    }

    public static void storeCertFile(X509Certificate cert, OutputStream ostream) throws Exception {
        storePem(cert, ostream, null);
    }

    public static void storeCertFile(X509Certificate[] cert, OutputStream ostream) throws Exception {
        storePem(cert, ostream, null);
    }

    public static void storeCRLFile(X509CRL x509CRL, OutputStream ostream) throws Exception {
        storePem(x509CRL, ostream, null);
    }

    public static void storeKeyFile(PublicKey pubKey, OutputStream ostream) throws Exception {
        storePem(pubKey, ostream, null);
    }

    public static void storeKeyFile(PrivateKey privKey, OutputStream ostream, char[] passwd) throws Exception {
        storePem(privKey, ostream, passwd);
    }

    public static void storeKeyFile(KeyPair keyPair, OutputStream ostream, char[] passwd) throws Exception {
        storePem(keyPair, ostream, passwd);
    }

    private static void storePem(Object obj, OutputStream ostream, char[] pwd) throws Exception {
        if (obj == null || ostream == null)
            return;

        PEMWriter pemWriter = new PEMWriter(new PrintWriter(ostream));
        if (pwd == null) {
            pemWriter.writeObject(obj);
        } else {
            JcePEMEncryptorBuilder encryptorBuilder = new JcePEMEncryptorBuilder(DES_EDE3_CBC)
                    .setProvider(JCE_PROVIDER).setSecureRandom(new SecureRandom());
            pemWriter.writeObject(obj, encryptorBuilder.build(pwd));
        }
        pemWriter.flush();
        pemWriter.close();
    }

    private static void storePem(Object[] obj, OutputStream ostream, char[] pwd) throws Exception {
        if (obj == null || ostream == null)
            return;

        PEMWriter pemWriter = new PEMWriter(new PrintWriter(ostream));
        for (int i = 0; i < obj.length; i++) {
            if (obj[i] == null)
                continue;
            if (pwd == null) {
                pemWriter.writeObject(obj[i]);
            } else {
                JcePEMEncryptorBuilder encryptorBuilder = new JcePEMEncryptorBuilder(DES_EDE3_CBC)
                        .setProvider(JCE_PROVIDER).setSecureRandom(new SecureRandom());
                pemWriter.writeObject(obj, encryptorBuilder.build(pwd));
            }

        }
        pemWriter.flush();
        pemWriter.close();
    }

}