Configuration of secret key storage in WebSphere Application Server

Configuration of secret key storage in WebSphere Application Server

Hi all,

this time I want to introduce a more development related blog post. Anyway this is a very interesting topic for an IBM Connections / WebSphere Administrator!!!

We have a self-registration application for IBM Connections / WebSphere Portal that stores configuration data (e.g. password of a LDAP bind User) in a property file. This password should not be stored unencrypted! My colleague Konstantin thought about the possibilities how to encrypt those passwords.

There is either the possibility to do it the „WebSphere Way“:

WebSphere Application Server encodes passwords for e.g. JDBC resources only by „XORing“ them. You can find a lot of those passwords in the security.xml file in the cell-root:

Bildschirmfoto 2015-03-12 um 09.44.03

When you now goto:

http://www.sysman.nl/wasdecoder/

you can decode the password easily:

Bildschirmfoto 2015-03-12 um 09.45.23

So not really safe the whole thing…

But we are Administrators and Developers so we can find another smarter solution for this 😉

Konstantin had the great idea to encrypt and decrypt passwords and configuration data using a shared secret. The shared secret is stored in a WebSphere key store… Yep, where you normally store SSL Certificates you can also store other things. The big advantage using a WebSphere key store is that you do not need to take care about passwords (think about a p12 key store file – you need to have a password to read the content). WebSphere takes care of this and you do not need to provide passwords when reading such a key store.

Konstantin did change his code so that one can enter a plaintext password in the property file with the prefix „encrypt:“ … When starting the application, the password gets encrypted. This is a very similar procedure used by IBM when configuring the TDI AssemblyLine (profiles_tdi.properties):

Bildschirmfoto 2015-03-12 um 10.29.34

Here you enter “{protect}-“ in front of the property and enter a plaintext password. When running the assembly line the password gets encoded.

And here is how you need to setup the keystore:

1. generate a secret key and save it in a keystore

cd /ibm/WebSphere/AppServer/java/bin
./keytool -genseckey -alias mykey -keystore /ibm/config/myKeystore.jsk -storepass mypassword -storetype JCEKS

2. Go to the WebSphere administration console, “SSL certeficate and key management” -> “Key stores and certificates” , select “Key set keystores” in the dropdown and click “New…”.

key1

3. Enter the path to the keystore you have just created in the command line and the password you used when creating the keystore. The type should be “JCEKS” and the readonly checkbox checked.

key2

4. create new key set:
Enter “userManager” as the key set name.
Select the newly created keystore and uncheck the “Generates key pair” checkbox. Click “Apply”

key3

5. go to the “Active key history” and click the “Add key reference” button.
As “alias reference” enter the name of the key you have created in the command line. Enter the key password you entered when creating the key.

key4

6. “Ok” and “save”. The key is ready to use.

That`s it. You now need to recode your application to encrypt / decrypt values in the property file. Furthermore you need to read the shared secred from the keystore.

It is rather easy to get the keys from the key store using the WebSphere API:

com.ibm.websphere.crypto.KeySetHelper ksh = KeySetHelper.getInstance();
SecretKey key = (SecretKey) ksh.getLatestKeyForKeySet(keySetName);

If you are interested in some more details regarding how to use the crypt service, just use the comment function – I will post some more code examples.

Code example

We`re using a class that can retrieve the key:

 public SecretKey getKey() throws KeyException{
        KeySetHelper ksh = KeySetHelper.getInstance();

            Object key = ksh.getLatestKeyForKeySet(keySetName);
            if (key == null) {
                throw new RuntimeException(
                        "Error getting key from key set, check the configuration of the key store and the key set");
            }
            return (SecretKey) key;
    }

The class KeySetHelper is taken from the ws-runtime-xx.jar that is available in WebSphere and needs to be provided.
Then we`re using another mothod to encode / decode:

 public String encrypt(String input) throws NoSuchAlgorithmException, NoSuchPaddingException {
        Cipher cipher;
    
            cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

            cipher.init(Cipher.ENCRYPT_MODE, keyProvider.getKey(), ivSpec);
            return new String(Base64.encodeBase64(cipher.doFinal(input.getBytes())));
       
    }

    public String decrypt(String input) throws NoSuchAlgorithmException, NoSuchPaddingException{
        Cipher cipher;
        
            cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keyProvider.getKey(), ivSpec);

            return new String(cipher.doFinal(Base64.decodeBase64(input.getBytes())));
        
    }

That`s all 😉

5 thoughts on “Configuration of secret key storage in WebSphere Application Server

    • Hi,

      it is contained in the ws-runtime-xxx.jar file – available in WebSphere.

      Julius

  1. Hello,

    Very good useful information. Could you please share some sample code to use it in the Java application?

    • Hi Boobalan,

      I added some code to initialize, encode and decode the keys. Hope this helps!

      Julius

      • I am getting NullPointerException
        at com.ibm.ws.crypto.config.WSKeySet.getLatestKey(WSKeySet.java:262)
        at com.ibm.websphere.crypto.KeySetHelper.getLatestKeyForKeySet(KeySetHelper.java:389)
        when calling ksh.getLatestKeyForKeySet(keySetName); where ksh is defined as KeySetHelper ksh = KeySetHelper.getInstance();

        Can you please guide the reason. The same thing is working fine on my local machine but when I deploy it on upper Environment its breaking at this place.

Leave a Reply

Your email address will not be published. Required fields are marked *