16

I am looking for an example or tutorial to generate X509 Certificates using BC in Java.

A lot of example are having/using deprecated API. I gave a look at BC, but it doesn't show which class does what or no proper documentation/example.

Please If any one you are having idea about it, please point me to a tutorial where I can use BC to generate X509 Certificates. [Generation and writing the public and private keys to files]

RaceBase
  • 18,428
  • 47
  • 141
  • 202
  • http://stackoverflow.com/questions/9938079/generating-x509certificate-using-bouncycastle-x509v3certificatebuilder – abRao Feb 18 '13 at 06:06

2 Answers2

16

Creation of KeyPairGenerator:

private KeyPairGenerator createKeyPairGenerator(String algorithmIdentifier,
        int bitCount) throws NoSuchProviderException,
        NoSuchAlgorithmException {
    KeyPairGenerator kpg = KeyPairGenerator.getInstance(
            algorithmIdentifier, BouncyCastleProvider.PROVIDER_NAME);
    kpg.initialize(bitCount);
    return kpg;
}

Creation of keyPair:

private KeyPair createKeyPair(String encryptionType, int byteCount)
    throws NoSuchProviderException, NoSuchAlgorithmException
{
    KeyPairGenerator keyPairGenerator = createKeyPairGenerator(encryptionType, byteCount);
    KeyPair keyPair = keyPairGenerator.genKeyPair();
    return keyPair;
}

KeyPair keyPair = createKeyPair("RSA", 4096);

Converting things to PEM (can be written to file):

  private String convertCertificateToPEM(X509Certificate signedCertificate) throws IOException {
    StringWriter signedCertificatePEMDataStringWriter = new StringWriter();
    JcaPEMWriter pemWriter = new JcaPEMWriter(signedCertificatePEMDataStringWriter);
    pemWriter.writeObject(signedCertificate);
    pemWriter.close();
    return signedCertificatePEMDataStringWriter.toString();
  }

Creation of X509Certificate:

X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(
    serverCertificate, new BigInteger("1"),
    new Date(System.currentTimeMillis()),
    new Date(System.currentTimeMillis() + 30L * 365L * 24L * 60L * 60L * 1000L),
    jcaPKCS10CertificationRequest.getSubject(),
    jcaPKCS10CertificationRequest.getPublicKey()
/*).addExtension(
    new ASN1ObjectIdentifier("2.5.29.35"),
    false,
    new AuthorityKeyIdentifier(keyPair.getPublic().getEncoded())*/
).addExtension(
        new ASN1ObjectIdentifier("2.5.29.19"),
        false,
        new BasicConstraints(false) // true if it is allowed to sign other certs
).addExtension(
        new ASN1ObjectIdentifier("2.5.29.15"),
        true,
        new X509KeyUsage(
            X509KeyUsage.digitalSignature |
                X509KeyUsage.nonRepudiation   |
                X509KeyUsage.keyEncipherment  |
                X509KeyUsage.dataEncipherment));

Signing:

    ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withRSA").build(signingKeyPair.getPrivate());


    X509CertificateHolder x509CertificateHolder = certificateBuilder.build(sigGen);
    org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure =
      x509CertificateHolder.toASN1Structure();
    return eeX509CertificateStructure;
  }

  private X509Certificate readCertificateFromASN1Certificate(
    org.spongycastle.asn1.x509.Certificate eeX509CertificateStructure,
    CertificateFactory certificateFactory)
    throws IOException, CertificateException { //
    // Read Certificate
    InputStream is1 = new ByteArrayInputStream(eeX509CertificateStructure.getEncoded());
    X509Certificate signedCertificate =
      (X509Certificate) certificateFactory.generateCertificate(is1);
    return signedCertificate;
  }

CertificateFactory:

    certificateFactory = CertificateFactory.getInstance("X.509",
        BouncyCastleProvider.PROVIDER_NAME);
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • 2
    **update: don't use SHA1** for certificate signature. It was already officially obsolete in 2014 (NIST SP800-57 for US govt, CABforum BR for web, but browsers didn't enforce the latter until late 2015 or 2016) and in 2017-02 the Stevens group plus google found an actual SHA1 collision so nearly all implementations, including Java 8u141 up, now prohibit it. – dave_thompson_085 Nov 09 '19 at 00:06
  • Definitely use SHA256 instead. – EpicPandaForce Nov 09 '19 at 11:02
9

The X509v3CertificateBuilder seems like the class to use. There are some examples of using the new API on the bouncycastle wiki.

President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • 1
    I hear @GregS is [reassuringly expensive](http://en.wikipedia.org/wiki/Reassuringly_Expensive) to hire by the hour. – Duncan Jones Feb 19 '13 at 19:15