如何在 java 中使用 bouncycastle 生成具有主题替代名称的 CSR

Posted

技术标签:

【中文标题】如何在 java 中使用 bouncycastle 生成具有主题替代名称的 CSR【英文标题】:How to use bouncycastle in java to generate a CSR with a subject alternative name 【发布时间】:2021-11-01 08:40:00 【问题描述】:

经过一番搜索,我想出了以下内容:

        PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
            new X500Principal("CN=clustername"), publicKey);
        

        ASN1Encodable[] subjectAlternativeNames2 = new ASN1Encodable[] 
                new GeneralName(GeneralName.rfc822Name, "clusteruid"),
                new GeneralName(GeneralName.dNSName, "127.0.0.1")
        ;
        DERSequence subjectAlternativeNamesExtension = new DERSequence(subjectAlternativeNames2);
        p10Builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, subjectAlternativeNamesExtension);//.addExtension(Extension.subjectAlternativeName, false, subjectAlternativeNames);
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("MD5WithRSA");
        ContentSigner signer = csBuilder.build(privateKey);
        PKCS10CertificationRequest thecsr = p10Builder.build(signer);

        out = new FileOutputStream(outFile + "x.csr");
        out.write("-----BEGIN CERTIFICATE REQUEST-----\n".getBytes());
        out.write(Base64.getEncoder().encodeToString(thecsr.getEncoded()).getBytes());
        out.write("\n-----END CERTIFICATE REQUEST-----\n".getBytes());
        out.close();

上述“似乎”工作,并按预期生成文件/tmp/licensingx.csr.included

我一直在使用 openssl 来验证。当我使用时:

openssl req -in /tmp/licensingx.csr -text -noout

我期待在输出中看到如下内容:

请求的扩展: X509v3 主题备用名称: EMAIL:clusterid, DNS:127.0.0.1

事实上,请求的扩展部分已丢失。任何人都可以提出一些建议吗?我们已经在主题中使用集群名称作为 CN。

【问题讨论】:

如果您希望从 Web 应用程序生成 CSR 和下载证书,请参考***.com/a/68556286/9659885 【参考方案1】:

经过更多搜索,我发现我缺少一层包装。结果:

    PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
        new X500Principal("CN=clustername"), publicKey);
    

    ASN1Encodable[] subjectAlternativeNames2 = new ASN1Encodable[] 
            new GeneralName(GeneralName.rfc822Name, "clusteruid"),
            new GeneralName(GeneralName.dNSName, "127.0.0.1")
    ;
    DERSequence subjectAlternativeNamesExtension = new DERSequence(subjectAlternativeNames2);
        
    ExtensionsGenerator extGen = new ExtensionsGenerator();
    extGen.addExtension(Extension.subjectAlternativeName, true,subjectAlternativeNamesExtension);
        
    
    p10Builder.addAttribute( PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
    JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("MD5WithRSA");
    ContentSigner signer = csBuilder.build(privateKey);
    PKCS10CertificationRequest thecsr = p10Builder.build(signer);

    out = new FileOutputStream(outFile + "x.csr");
    out.write("-----BEGIN CERTIFICATE REQUEST-----\n".getBytes());
    out.write(Base64.getEncoder().encodeToString(thecsr.getEncoded()).getBytes());
    out.write("\n-----END CERTIFICATE REQUEST-----\n".getBytes());
    out.close();

【讨论】:

以上是关于如何在 java 中使用 bouncycastle 生成具有主题替代名称的 CSR的主要内容,如果未能解决你的问题,请参考以下文章

使用 Bouncycastle 在 Java 中进行格式保留加密 (FPE)

如何添加BouncyCastle的算法到Android

Java 中带有 bouncycastle 的 PBKDF2

使用Java中的bouncycastle生成p7b证书链

在没有 BouncyCastle 的情况下用 Java 创建 X509 证书?

向证书请求添加属性,java + bouncycastle 1.48