簡體   English   中英

使用BouncyCastle為java.security.Keystore生成自簽名證書的簡單方法

[英]Easy way to generate a self-signed certificate for java.security.Keystore using BouncyCastle

我有一個使用BouncyCastle生成RSA密鑰對的應用程序。 我想將該密鑰對存儲在java.security.Keystore中。 為此,我需要證書(唯一需要證書的原因!)。

我正在使用Bouncycastle 1.51版。

我發現的所有示例都使用* CertificateGenerator(在1.51中棄用),或者非常復雜,沒有任何有意義的解釋。

為此目的生成基本無意義的自簽名證書的最簡單方法是什么?

還是有使用密鑰庫的替代方法?

需要明確的是:輸入是包含RSAPrivateKey和RSAPublicKey的KeyPair,輸出應該是java.security.cert.Certificate。

我最終使用的解決方案看起來像下面的代碼(雖然不漂亮,但是可以工作):

import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;
import java.sql.Date;

import javax.security.auth.x500.X500Principal;

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v1CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

public class SelfSignedCertificateGenerator {

    private static final JcaX509CertificateConverter CONVERTER = new JcaX509CertificateConverter()
        .setProvider(new BouncyCastleProvider());

    private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";

    private static final X500Name ISSUER = new X500Name(new X500Principal("CN=Stupid CA Certificate").getName());
    private static final X500Name SUBJECT = ISSUER;
    private static final Date NOT_AFTER = Date.valueOf("3000-01-01");
    private static final Date NOT_BEFORE = Date.valueOf("2000-01-01");
    private static final BigInteger SERIAL = new BigInteger("1");

    public static Certificate[] getCerts(KeyPair keys) {
        return new Certificate[] { getCertificate(keys) };
    }

    private static X509Certificate getCertificate(KeyPair keys) {
        try {
            X509v1CertificateBuilder certificateBuilder = getCertificateBuilder(keys.getPublic());
            X509CertificateHolder certificateHolder = certificateBuilder.build(getSigner(keys));
            return CONVERTER.getCertificate(certificateHolder);
        } catch (CertificateException e) {
            throw new RuntimeException(e);
        }
    }

    private static X509v1CertificateBuilder getCertificateBuilder(PublicKey publicKey) {
        return new X509v1CertificateBuilder(ISSUER, SERIAL, NOT_BEFORE, NOT_AFTER, SUBJECT, getPublicKeyInfo(publicKey));
    }

    private static SubjectPublicKeyInfo getPublicKeyInfo(PublicKey publicKey) {
        if (!(publicKey instanceof RSAPublicKey))
            throw new RuntimeException("publicKey is not an RSAPublicKey");

        RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;

        try {
            return SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(new RSAKeyParameters(false, rsaPublicKey
                .getModulus(), rsaPublicKey.getPublicExponent()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static ContentSigner getSigner(KeyPair keys) {
        try {
            return new JcaContentSignerBuilder(SIGNATURE_ALGORITHM).setProvider(new BouncyCastleProvider()).build(
                keys.getPrivate());
        } catch (OperatorCreationException e) {
            throw new RuntimeException(e);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM