Showing posts with label JKS. Show all posts
Showing posts with label JKS. Show all posts

Dumping out JKS private key

This post explains how you could programmatically access a java key store and dump its private key out.

To start with, let's create a key store with java keytool.

C:\>keytool -genkey -keystore wso2.jks -storepass wso2123 -keypass wso2123 -alias wso2
Let's look at the code now. It's self-explanatory with the attached comments.

package org.wso2;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;

public class KeyExplorer {

private final static String KEY_STORE_FILE = "c:\\wso2.jks";
private final static String KEY_STORE_PASSWORD = "wso2123";
private final static String PRIVATE_KEY_PASSWORD = "wso2123";
private final static String KEY_ALIAS = "wso2";
private final static String KEY_STORE_TYPE = "jks";
private final static String OUT_PUT_FILE = "c:\\wso2.key";

public static void main(String[] args) {

KeyStore keystore = null;
Key privateKey = null;
FileOutputStream outFile = null;

try {
keystore = KeyStore.getInstance(KEY_STORE_TYPE);
keystore.load(new FileInputStream(KEY_STORE_FILE), KEY_STORE_PASSWORD.toCharArray());

if (keystore.containsAlias(KEY_ALIAS)) {
privateKey = keystore.getKey(KEY_ALIAS, PRIVATE_KEY_PASSWORD.toCharArray());
} else {
return;
}

// Returns true if the entry identified by the given alias was
// created by a call to setKeyEntry, or created by a call to
// setEntry with a PrivateKeyEntry or a SecretKeyEntry.
if (keystore.isKeyEntry(KEY_ALIAS)) {
System.out.println("PrivateKeyEntry");
}

// Returns the standard algorithm name for this key. For example,
// "DSA" would indicate that this key is a DSA key.
System.out.println("Algorithm: " + privateKey.getAlgorithm());

// Returns the name of the primary encoding format of this key, or
// null if this key does not support encoding. The primary encoding
// format is named in terms of the appropriate ASN.1 data format, if
// an ASN.1 specification for this key exists. For example, the name
// of the ASN.1 data format for public keys is SubjectPublicKeyInfo,
// as defined by the X.509 standard; in this case, the returned
// format is "X.509". Similarly, the name of the ASN.1 data format
// for private keys is PrivateKeyInfo, as defined by the PKCS #8
// standard; in this case, the returned format is "PKCS#8".
System.out.println("Key format: " + privateKey.getFormat());

outFile = new FileOutputStream(OUT_PUT_FILE);
outFile.write(privateKey.getEncoded());
outFile.flush();

} catch (Exception e) {
e.printStackTrace();
} finally {
if (outFile != null) {
try {
outFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
The above will output the private key in a binary format - let's see how we could convert it to Base64 with OpenSSL.

You can download OpenSSL for Windows from here.

openssl enc -in wso2.key -out wso2-txt.key -a
The "enc" command does various types of encryptions and encodings and "-a" is for Base64 - just type "openssl enc -help" - you'll see all available options.

Creating a new JKS with an existing private key and a signed certificate

You have your own private key and a CA signed certificate - and now you want to import both the key and the certificate to a new JKS.

This is how we do it and you need to have OpenSSL installed.

For Windows you can download Win32 OpenSSL v0.9.8g from here.Once installed make sure you add C:\OpenSSL\bin [i.e [INSTALLED_LOCATION]\bin] to the PATH env variable.

If your key and certificate are in PEM format, then you need to convert them into DER format. [privateKey.pem & signedCert.pem]

:\> openssl pkcs8 -topk8 -nocrypt -in privateKey.pem -inform PEM -out privateKey.der -outform DER

:\>openssl x509 -in signedCert.pem -inform PEM -out signedCert.der -outform DER


Copy the resulted signedCert.der and privateKey.der to c:\keys.

Java keytool does not support a direct way of importing an existing private key to a new key store. So, we'll be doing it programmatically.

You can download the code from here and copy it to c:\keys.

c:\keys\>javac BuildJKS.java

c:\keys\>java BuildJKS privateKey.der signedCert.der mykeyalias MyJKS.jks keypassword storepassword


The above will create a JKS with the name MyJKS.jks and the key store password will be storepassword while the private key password is keypassword. Also the alias of the imported key is mykeyalias.

To verify that the JKS being created properly just issue the following command to list certificates stored in the key store.

c:\keys\>keytool -list -keystore MyJKS.jks -storepass storepassword