Monday, December 10, 2012

Generating Certificates With BouncyCastle

Usually, after a serious public-private key generation session, the private key would need to be stored. The obvious place would be a key store. The commonly used method to accomplish this using class:

void setKeyEntry(String alias, byte[] key, Certificate[] chain) 

You'll need at least one Certificate object to accompany the private key. You may be tempted (or already attempted) to 'skip' producing the Certificate object using this method:

void setEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam)

But you'll discover that a object needs a Certificate[] object passed in as well.

This led to the code below to generate the required Certificate object, just enough to fulfil the requirements to save the private key:

 private Certificate[] generateCertificateOld(KeyPair keyPair) throws Exception {
        Date startDate = new Date(System.currentTimeMillis());
        Date expiryDate = DateUtils.parseDate("01/01/2100", new String[] { "dd/MM/yyyy" });
        BigInteger serialNumber = new BigInteger(String.valueOf(System.currentTimeMillis()));

        X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
        X500Principal dnName = new X500Principal("CN=Storage Certificate");

        certGen.setSubjectDN(dnName); // note: same as issuer

        return new Certificate[] {certGen.generate(keyPair.getPrivate())};

Of course, if you have the aid of an IDE, the BouncyCastle methods used are deprecated (using v1.47). So, being a good Java coder, I've followed the advice in the BC javadocs and replaced the deprecated methods with the following equivalent code:

 private Certificate[] generateCertificate(KeyPair keyPair) throws Exception {
  X509v1CertificateBuilder certGen = new JcaX509v1CertificateBuilder(
    new X500Name("CN=Storage Certificate"),
    new Date(System.currentTimeMillis()),
    DateUtils.parseDate("01/01/2100", new String[] { "dd/MM/yyyy" }),
    new X500Name("CN=Storage Certificate"),

  JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA256withRSA");
  ContentSigner contentSigner =;
  X509CertificateHolder certHolder =;

  JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
  Certificate cert = certConverter.getCertificate(certHolder);

  Certificate[] certs = { cert };
  return certs;

May your sanity be in check as you navigate through the waters of Java security.

No comments: