Monday, June 4, 2012

How to create x509 certificate in Java


Here is method which creates x509 self signed certificate. Only problem is that it is using sun.security.* packages which are considered internal and Sun/Oracle Java only.

   /**
    * X509 certificate creation based on JCE and sun.security packages. Works
    * for Oracle JDK and OpenJDK.
    * @param dn
    * @param pair
    * @param days
    * @param algorithm
    * @return
    * @throws GeneralSecurityException
    * @throws IOException
    */
   static 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 algorithm, 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;
   }