java - 使用 BouncyCaSTLe 为 java.security.Keystore 生成自签名证书的简单方法

标签 java cryptography certificate bouncycastle

我有一个使用 BouncyCaSTLe 生成 RSA key 对的应用程序。我想将该 key 对存储在 java.security.Keystore 中。为此,我需要一个证书(我需要一个证书的唯一原因!)。

我使用的是 1.51 版的 bouncycaSTLe。

我在这方面找到的所有示例要么使用 *CertificateGenerator(在 1.51 中弃用),要么非常复杂且没有任何有意义的解释。

为此目的生成基本上没有意义的自签名证书的最简单方法是什么?

或者是否有使用 keystore 的替代方法?

明确一点:输入是包含 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);
        }
    }
}

关于java - 使用 BouncyCaSTLe 为 java.security.Keystore 生成自签名证书的简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28538785/

相关文章:

java - getParameter() 使用 post 方法返回 null 值

java - 在 Eclipse 上使用 jss7 构建 ATI 客户端

xcode - 代码签名错误,如何将 Xcode 项目切换到另一台 Mac?

ssl - Meteor - 如何使用 POST 请求为 Meteor 中的 *client* 身份验证提交 SSL 证书?

java - 如何调试服务器端错误?

java - xml使用sax解析器从子标签解析数据

c# - SHA256 的 RSACryptoServiceProvider.SignHash 返回 128 字节而不是 32?

.net - XML DSIG : Enveloping signature transform in . 网络

c# - 在 C# 和 NodeJS 中生成 PBKDF2 key

ios - 如何将 UDID 添加到配置文件中?