Create a PKCS10 request with alternate objects using Bouncy Castle in Java

I am currently using bouncy castle to create a PKCS10 request with one object per se:

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

Now I need to add item alternatives to the PKCS10 request. I could not figure out how to do this. Any suggestions?

DECISION:

Based on the great information provided in the second answer, I was able to figure this out. In the working code below, XName is a simple class containing the name and type of an object (DNS, RFC822, etc.).

        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();
+4
source share
1 answer

, , JcaPKCS10CertificationRequestBuilder ( API- 2), API- V1.

BC "X.509 " , API- 1, 212 Wrox " Java".

API- 2 , CSR.

, API v2, , , 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

- API v2.

, cert.test.PKCS10Test V2, . , JavaScript ASN1 , .

+2

Source: https://habr.com/ru/post/1619135/


All Articles