2015-12-09 31 views
4
使用充气城堡主题的选择PKCS10请求

我目前使用的充气城堡,以创建一个单一的主题为这样的PKCS10要求:建立在Java

X500Principal subject = new X500Principal("CN=foo.bar.com"); 
    PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(
      subject, publicKey); 

我现在需要受到替代品添加到PKCS10请求。我一直无法弄清楚如何做到这一点。有什么建议么?

SOLUTION:

根据在第2个答案我能想出解决办法提供了巨大的信息。在下面的工作代码中,XName是一个包含主题名称和名称类型(DNS,RFC822等)的简单类。

 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(); 
+0

请将您的**解答**部分移至答案并将其标记为已接受。 –

回答

2

我有同样的问题迈克,我觉得你的问题涉及到试图使用过时的API V1为此使用JcaPKCS10CertificationRequestBuilder(从第2版API)来代替。

如果您访问BC维基页面并查找"X.509 Public Key Certificate and Certificate request generation",那么对版本1 API的处理有一个合理的描述,这与David Hook撰写的Wrox书籍第212页上的列表非常相似,“用Java开始加密“。

在描述如何创建CSR时,关于第2版API的wiki文档非常差。

总结如何使用V2的API,这里的一些代码,我有工作这是基于他们的V2测试的情况下(全班同学寻找的是下面这段代码清单):

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 

我d建议仔细查看专门针对v2 API的wiki页面。

很重要的是,一旦你找到了cert.test.PKCS10Test对于V2的源代码,这一切都开始有意义。最后,我使用this JavaScript hex dumper for ASN1 来检查它是否正确出来。

+0

非常感谢您的帮助!我已经根据你的代码实现了一个解决方案。请参阅我的原始文章中的“解决方案”。 –