java - 使用 bouncycaSTLe 创建证书

标签 java certificate bouncycastle

我正在尝试使用 bouncycaSTLe 库为 S/MIME 创建自签名证书。我使用了示例和互联网上的一些帖子。代码如下。

SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    Security.addProvider(new BouncyCastleProvider());
    KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");        
    kpGen.initialize(1024, random);
    KeyPair keyPair = kpGen.generateKeyPair();
    PublicKey RSAPubKey = keyPair.getPublic();
    PrivateKey RSAPrivateKey = keyPair.getPrivate();
    X500Name subjectDN = new X500Name("CN =" + domain);        
    SubjectPublicKeyInfo pubKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(RSAPubKey.getEncoded()));
    X509v3CertificateBuilder v3CertBuild;
    v3CertBuild = new X509v3CertificateBuilder(subjectDN,
            BigInteger.valueOf(new SecureRandom().nextInt()),
            new Date(System.currentTimeMillis()),
            new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10)),
            subjectDN,
            pubKeyInfo);
    DigestCalculator digCalc = new BcDigestCalculatorProvider().get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
    X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(digCalc);
    v3CertBuild.addExtension(Extension.authorityKeyIdentifier, false, x509ExtensionUtils.createAuthorityKeyIdentifier(pubKeyInfo).getKeyIdentifier());
    v3CertBuild.addExtension(Extension.subjectKeyIdentifier, false, x509ExtensionUtils.createSubjectKeyIdentifier(pubKeyInfo).getKeyIdentifier());
    v3CertBuild.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
    ASN1EncodableVector purposes = new ASN1EncodableVector();
    purposes.add(KeyPurposeId.id_kp_emailProtection);
    v3CertBuild.addExtension(Extension.extendedKeyUsage, false, purposes.get(0));
    v3CertBuild.addExtension(Extension.basicConstraints, true, new BasicConstraints(0));
    GeneralName[] genNames = new GeneralName[1];
    genNames[0] = new GeneralName(GeneralName.rfc822Name, new DERIA5String(domain));
    v3CertBuild.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(genNames));
    ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(RSAPrivateKey);
    X509Certificate certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertBuild.build(sigGen));
    PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) certificate;
    bagAttr.setBagAttribute(
            PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
            new DERBMPString(domain));
    KeyStore kstore = KeyStore.getInstance("PKCS12", "BC");
    X509Certificate[] chain = new X509Certificate[1];
    chain[0] = certificate;
    kstore.load(null, null);        
    FileOutputStream fOut = new FileOutputStream(domain+".p12");
    PKCS12BagAttributeCarrier bagAttr1 = (PKCS12BagAttributeCarrier) keyPair.getPrivate();
    bagAttr1.setBagAttribute(
            PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
            new DERBMPString(domain));
    bagAttr.setBagAttribute(
        PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
            new SubjectKeyIdentifier(RSAPubKey.getEncoded()));            
    kstore.setKeyEntry(domain, RSAPrivateKey, null, chain);
    kstore.store(fOut, password.toCharArray());

我有一个异常(exception):

java.lang.RuntimeException: java.io.IOException: DER length more than 4 bytes: 39
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineGetCertificateChain(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.getUsedCertificateSet(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.doStore(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineStore(Unknown Source)
at java.security.KeyStore.store(KeyStore.java:1377)
at javaapplication1.Certificate.createCert(Certificate.java:91)
at javaapplication1.JavaApplication1.main(JavaApplication1.java:38)

或者有时:

java.lang.RuntimeException: java.io.IOException: unknown tag 29 encountered
java.lang.RuntimeException: java.io.EOFException: DEF length 64 object truncated by 46

它停在最后一行。搜索了很多有关此异常的信息,但仍然无法理解我的代码出了什么问题。请帮我找到解决方案...

最佳答案

错误在于:

v3CertBuild.addExtension(Extension.authorityKeyIdentifier, false, x509ExtensionUtils.createAuthorityKeyIdentifier(pubKeyInfo).getKeyIdentifier());
v3CertBuild.addExtension(Extension.subjectKeyIdentifier, false, x509ExtensionUtils.createSubjectKeyIdentifier(pubKeyInfo).getKeyIdentifier());

getKeyIndentifier() 是不必要的...

关于java - 使用 bouncycaSTLe 创建证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42061780/

相关文章:

java - 使用多个按钮创建弹出选项框

java - 通过DER算法解码Java中的证书

ios - 发布推送通知应用程序

c# - SecureRandom 漏洞也适用于 BouncyCaSTLe C#

java - Bouncy CaSTLe 中的 TLS-SRP 支持

java - 私有(private)方法上的@Transactional 传播

java - 如何将 POJO 插入到键值数据库表中?

java - 限制 Java 控制台堆占用空间?

iOS 分发证书即将到期。我有什么选择?

ssl - 我们可以在 Blackberry 中通过 TLS 客户端和 TLS 协议(protocol)为 http url 创建套接字连接吗?