Reading private key from WebSphere Application Server’s keystore

Java logo

Introduction

Not so long ago, one of my customer asked, can he read a private key from the WebSphere Application Server’s (WAS) own keystore to use the private key for a purpose (let’s say, sign a document).

We all know the possibility, that reading a private or public key using Java is quite easy when you know the exact location and password for the keystore file. However, when you are using your code in a managed environment (or on a Java application server), the keystore and truststore locations are hidden from the code. Even, when you are deploying the application onto a clustered environment.

So, the aim is to use the application server’s API/interface/SPI whatever, to gain access to those stores, and be able to use the keys and/or certificates.

Unfortunately, the WebSphere documentation is not mentioning this on a very detailed way, and that was the reason the customer came to me.

Let’s see, how can you get the keys from WAS.

Theory

To be able to use WAS stored keys (regardless those are private or public keys), you need to know, where to find them. If you are familiar with WAS, the term of scope is not a strange thing to you.

Example scope:

(cell):MyWASCell01:(node):MyWASNode01:(server):MyWASServer01

The above scope example has the following explanation:

(cell):MyWASCell01: identify the WAS cell named as MyWASCell01

(node):MyWASNode01: identify the WAS node within the cell named MyWASNode01

(server):MyWASServer01: identify the WAS server on node MyWASNode01 in cell MyWASCell01

So, to get a key from a WAS managed keystore, you need a similar scope definiton like above. For a better explanation, we are „hardcoding” this definiton into the Java code, but you can you the WAS’ Mbeans to dynamically query those scope information at runtime if you wish. For now, gather it from the WAS admin console.

In my case, the scope will be the following:

(cell):BPMPC856Cell:(node):BPMPC856CustomNode

The next thing you need to know, which store you want to get access to. In my case, it will be the NodeDefaultKeyStore. The store names also can be gathered from the WAS admin console.

And a last thing, you need the password for the chosen store.

Implementation

Now we have all the neccessary information to programatically access a key or trust store using Java, running on WAS.

Let’s create the code. For an easy demonstration, I simply created a WebServlet, and inside the doGet() method, I will read a key, which will be WAS default private key, named default (the key alias).

@Override
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
    try {
        KeyStore keyStore = KeyStoreManager.getInstance().getJavaKeyStore("NodeDefaultKeyStore", "(cell):BPMPC856Cell:(node):BPMPC856CustomNode");
        Key key = keyStore.getKey("default", "WebAS".toCharArray());
        System.out.println(key);
    } catch(Exception e) {
        e.printStackTrace();
    }
}

Simple is that. Actually to lines of code. The only WebSphere specific code here is the KeyManagerclass. The KeyManager class can be imported from the com.ibm.ws.ssl.config package, the rest of the code is standard Java.

Please be aware, that this code can be run on IBM Java, not Oracle. Which will be okay, when you are running it on WAS. 🙂

And the output when you execute the code will be the following on WAS’ SystemOut.log:

com.ibm.crypto.provider.RSAPrivateCrtKey@ffc21fa2

Happy key usage!