Home Download << "Emotion Timewave" Search Engine set to use BFO Graph Library | Home | Smaller, Faster, Better - BFO Release New PDF Library >> RSS feed

Odds and Ends: Creating a new X.509 Certificate

How to create a self-signed X.509 Certificate in Java

We've been busy integrating new ASN.1 code into our PDF API in preparation for a new release later this week, and one of the areas of code we needed was a way to create a new self-signed X.509 Certificate.

Java has a huge number of packages and classes related to security, X.509 and the like, including the X509Certificate class. However, code to create a new self-signed X.509 Certificate in Java is conspicuously absent, even though this functionality is available in the Java keytool application.

So without further ado, here's what we think is the simplest way to do it. This involves a call into the undocumented sun.security.x509 package used by keytool: so it's public and not likely to go away soon.

import sun.security.x509.*;
import java.security.cert.*;
import java.security.*;
import java.math.BigInteger;
import java.util.Date;
import java.io.IOException

/** 
 * Create a self-signed X.509 Certificate
 * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB"
 * @param pair the KeyPair
 * @param days how many days from now the Certificate is valid for
 * @param algorithm the signing algorithm, eg "SHA1withRSA"
 */  
X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
  throws GeneralSecurityException, IOException
{
  PrivateKey privkey = pair.getPrivate();
  X509CertInfo info = new X509CertInfo();
  Date from = new Date();
  Date to = new Date(from.getTime() + days * 86400000l);
  CertificateValidity interval = new CertificateValidity(from, to);
  BigInteger sn = new BigInteger(64, new SecureRandom());
  X500Name owner = new X500Name(dn);

  info.set(X509CertInfo.VALIDITY, interval);
  info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
  info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
  info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
  info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
  info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
  AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
  info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));

  // Sign the cert to identify the algorithm that's used.
  X509CertImpl cert = new X509CertImpl(info);
  cert.sign(privkey, algorithm);

  // Update the algorith, and resign.
  algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG);
  info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
  cert = new X509CertImpl(info);
  cert.sign(privkey, algorithm);
  return cert;
}   
Tags : ,


Re: Odds and Ends: Creating a new X.509 Certificate

Thanks Mike. Great info! Been looking all day to find something like this. Strange that this kind of functionality is not provided in the public APIs.

Cheers!

Re: Odds and Ends: Creating a new X.509 Certificate

Thanks man.  Really useful.

Re: Odds and Ends: Creating a new X.509 Certificate

Awesome, i've been looking for this for days. Thanks

Re: Odds and Ends: Creating a new X.509 Certificate

Wonderful!

Re: Odds and Ends: Creating a new X.509 Certificate

Awesome code! Thanks a lot Mike

Re: Odds and Ends: Creating a new X.509 Certificate

In reply to a slightly grumpy anonymous message I just received stating this was "ripped straight from the source code to KeyTool from OpenJDK":

As it happens I started with API docs and a decompiler for reference, although the 20 lines of code calling the same API to do exactly the same thing unsurprisingly have similarities.

Regardless, in a nod to my anonymous friend, the source for KeyTool is a useful aid to anyone working with X.509 certificates in Java.

Re: Odds and Ends: Creating a new X.509 Certificate

Thanks a lot buddy... Really useful. Cheers.

Re: Odds and Ends: Creating a new X.509 Certificate

Thank you very much.

Re: Odds and Ends: Creating a new X.509 Certificate

Awesome. Thanks so much for sharing :)