首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Java中的Bouncy城堡创建带有主题选项的PKCS10请求

使用Java中的Bouncy城堡创建带有主题选项的PKCS10请求
EN

Stack Overflow用户
提问于 2015-12-09 02:52:08
回答 1查看 6.7K关注 0票数 9

目前,我正在使用bouncy城堡创建一个PKCS10请求,其中只有一个主题:

代码语言:javascript
运行
复制
    X500Principal subject = new X500Principal("CN=foo.bar.com");
    PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(
            subject, publicKey);

现在,我需要在PKCS10请求中添加主题选项。我一直想不出该怎么做。有什么建议吗?

解决办法:

根据在第二个答案中提供的伟大信息,我能够弄清楚这一点。在下面的工作代码中,XName是一个简单的类,包含主题名称和名称类型(DNS、RFC822等)。

代码语言:javascript
运行
复制
        String signerAlgo = "SHA256withRSA";
        ContentSigner signGen = new JcaContentSignerBuilder(signerAlgo).build(privateKey);

        X500Principal subject = new X500Principal(csr.getSubjectAsX500NameString());

        PKCS10CertificationRequestBuilder builder = 
                new JcaPKCS10CertificationRequestBuilder(subject, publicKey);

        /*
         * Add SubjectAlternativeNames (SANs)
         */
        if (csr.getSubjectAlternatives() != null && csr.getSubjectAlternatives().size() > 0) {
            List<GeneralName> namesList = new ArrayList<>();
            for (XName subjectAlt : csr.getSubjectAlternatives()) {
                log.debug(m, d+2, "Adding SubjectAltName: %s", subjectAlt);
                namesList.add(GeneralNameTool.toGeneralName(subjectAlt));
            }

            /*
             * Use ExtensionsGenerator to add individual extensions.
             */
            ExtensionsGenerator extGen = new ExtensionsGenerator();

            GeneralNames subjectAltNames = new GeneralNames(namesList.toArray(new GeneralName [] {}));
            extGen.addExtension(Extension.subjectAlternativeName, false, subjectAltNames);
            builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());
        }

        PKCS10CertificationRequest request = builder.build(signGen);

        StringWriter writer = new StringWriter();
        JcaPEMWriter pem = new JcaPEMWriter(writer);
        pem.writeObject(request);
        pem.close();
EN

回答 1

Stack Overflow用户

发布于 2016-01-02 21:03:26

我也遇到了同样的问题,迈克,我认为您的问题与尝试使用JcaPKCS10CertificationRequestBuilder (来自版本2的API)而不是使用不受欢迎的V1 API有关。

如果您访问BC wiki页面并查找"X.509公钥证书和证书请求生成“,就有关于如何处理版本1 API的合理描述,这与David的Wrox书第212页上的清单非常相似,即“用Java开始密码学”。

但是,在描述如何创建CSR时,版本2 API的wiki文档非常糟糕。

为了总结如何使用v2 API,下面是一些基于V2测试用例的代码(下面是要查找的类):

代码语言:javascript
运行
复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import org.bouncycastle.asn1.DEROctetString;

import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;

...

X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);

// See e.g. http://javadox.com/org.bouncycastle/\
// bcprov-jdk15on/1.51/org/bouncycastle/asn1/x500/style/BCStyle.html
// for a description of the available RDNs

x500NameBld.addRDN(BCStyle.CN, commonName);
x500NameBld.addRDN(BCStyle.OU, orgCode);
x500NameBld.addRDN(BCStyle.UNIQUE_IDENTIFIER, "64 bit EUID goes here");

X500Name    subject = x500NameBld.build();

/**
 *  My application needs to set the Key Usage section of the CSR 
 * (which for my app has a Criticality of "true" and a value of
 * "digital signature" or "key agreement").
 */

 Extension[] extSigning = new Extension[] {
        new Extension(Extension.basicConstraints, true, 
           new DEROctetString(new BasicConstraints(true))),
           new Extension(Extension.keyUsage, true,
           new DEROctetString(new KeyUsage(KeyUsage.keyCertSign))),
  };

  Extension[] extKeyAgreement = new Extension[] {
        new Extension(Extension.basicConstraints, true, 
           new DEROctetString(new BasicConstraints(true))),
           new Extension(Extension.keyUsage, true, 
           new DEROctetString(new KeyUsage(KeyUsage.keyCertSign))),
   };

   PKCS10CertificationRequest req = 
     new JcaPKCS10CertificationRequestBuilder(
         subject,
         pair.getPublic())
         .addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
         new Extensions(isKaFlag==true?extKeyAgreement:extSigning))
         .build(new JcaContentSignerBuilder("SHA256withECDSA")
         .setProvider(BC)                         
         .build(pair.getPrivate()));

    return req;  // The PKCS10 certificate signing request

我建议仔细查看它们的wiki页面,特别是v2 API。

关键的是,一旦您找到了cert.test.PKCS10Test的V2源代码,就开始有意义了。最后,我使用这台JavaScript ASN1六角翻车机来检查它是否正确。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34169954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档