Private Key PFX to/from JKS Conversion Using OpenSSL and Jetty


Recently I’ve been watching quite a few screencasts which seem to be a really fun way to learn something. This made me want to create something of my own. So for this blog post I’m putting up my first attempts at creating screencasts while trying to explain something useful.

When dealing with PKI based application security, one usually encounters different systems on different platforms and making sure they can interact with each other can be quite a hassle. Testing these systems usually means you create you own self-signed private/public key pairs. And of course there are times when for testing purposes you need to convert your private key to another format because you generated it on a different platform or received it from someone else who didn’t ask you about your preferred private key storage format. There are quite a few storage formats devised by the public-key cryptography standards group. Most of the time I have to deal with keys in Java’s JKS format and PFX format used on Microsoft platforms so from time to time I have a need of converting one format into another. See the screencasts bellow of how I’m converting them both ways.

Convert private key in PFX format to JKS keystore

Note: after this conversion the alias in the Java keystore for the converted key is ‘1’. Since I’m using such conversions only for test purposes I haven’t looked into changing the alias to something more meaningful. But if you know a quick way of doing this without reimporting the key, please, post your method in the comments ;)

Convert private key in JKS keystore to PFX format

Here’s the source of the Java file I used in the screencast for private key an certificate extraction from JKS keystore. Note that I’m assuming here the usage of JDK 6 because System.console().readPassword() is used to read the password without echoing.

import java.io.*;
import java.security.*;
import java.security.cert.Certificate;

public class ExportKeyAndCert {

  private static class Base64 {
    static final byte[] encodeData;
    static final String charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    static {
      encodeData = new byte[64];
      for (int i = ; i < 64; i++) {
        byte c = (byte) charSet.charAt(i);
        encodeData[i] = c;
      }
    }

    private Base64() {}

    public static String encode(byte[] src) {
      int length = src.length;
      byte[] dst = new byte[(length + 2) / 3 * 4 + length / 57];
      int x = , len = , old = , state = , dstIndex = ;

      for (int srcIndex = ; srcIndex < length; srcIndex++) {
        x = src[srcIndex];
        switch (++state) {
          case 1:
          dst[dstIndex++] = encodeData[(x >> 2) & 0x3f];
          break;
          case 2:
          dst[dstIndex++] = encodeData[((old << 4) & 0x30) | ((x >> 4) & 0xf)];
          break;
          case 3:
          dst[dstIndex++] = encodeData[((old << 2) & 0x3C) | ((x >> 6) & 0x3)];
          dst[dstIndex++] = encodeData[x & 0x3F];
          state = ;
          break;
        }
        old = x;
        if (++len >= 57) {
          dst[dstIndex++] = (byte) '\n';
          len = ;
        }
      }
      switch (state) {
        case 1:
        dst[dstIndex++] = encodeData[(old << 4) & 0x30];
        dst[dstIndex++] = (byte) '=';
        dst[dstIndex++] = (byte) '=';
        break;
        case 2:
        dst[dstIndex++] = encodeData[(old << 2) & 0x3c];
        dst[dstIndex++] = (byte) '=';
        break;
      }
      return new String(dst);
    }
  }

  static public void main(String[] args) {
    if (args.length < 2) {
      System.out.println("Usage: java ExportKeyAndCert keyStore keyAlias");
      System.exit();
    }
    try {
      String keyStore = args[0];
      String keyAlias = args[1];
      Console console = System.console();
      char[] storePass = console.readPassword("Enter keystore password: ");
      char[] keyPass = console.readPassword("Enter key password: ");

      KeyStore ks = KeyStore.getInstance("jks");
      ks.load(new FileInputStream(keyStore), storePass);

      Certificate cert = ks.getCertificate(keyAlias);
      String b64 = Base64.encode(cert.getEncoded());

      PrintWriter fout = new PrintWriter("public.cer");
      fout.println("-----BEGIN CERTIFICATE-----");
      fout.println(b64);
      fout.println("-----END CERTIFICATE-----");
      fout.close();

      Key key = ks.getKey(keyAlias, keyPass);
      b64 = Base64.encode(key.getEncoded());

      fout = new PrintWriter("private.key");
      fout.println("-----BEGIN PRIVATE KEY-----");
      fout.println(b64);
      fout.println("-----END PRIVATE KEY-----");
      fout.close();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}