Did you know IBM MQ supports PKCS#12 keystores? 2 years ago, when IBM MQ 9.3 LTS released, support for PKCS#12 keystores was included. In several conversations with customers recently it seems that we didn’t publicise this feature enough on release and so it has gone unnoticed. In this blog post I’ll talk about how to configure IBM MQ to use PKCS#12 keystores.
Note: When referring to client applications here I’m specifically talking about applications using the C libraries. Java/JMS applications have supported PKCS#12 keystores for a while as the IBM MQ libraries defer to the JRE mechanisms to indicate what keystore to use and what formats are supported. Additionally, Managed .NET uses the windows certificate store to provide the necessary certificates and keys.
How do I tell my queue manager or client application to use a PKCS#12 keystore?
The same attributes and fields that were used to tell a queue manager or client application to use a CMS keystore can be used to use a PKCS#12 keystore. These are the MQSC SSLKEYR attribute for the queue manager or for C client applications you have 3 choices: The KeyRepository field on the MQSCO structure, the MQSSLKEYR environment variable or the SSLKeyRepository attribute on the SSL stanza of the client configuration file mqclient.ini.
You may be familiar with these already and may remember that when providing a value, MQ expected the filename without the extension. This was because before 9.3 LTS IBM MQ would automatically append ‘.kdb’ to the provided value. MQ changed this behaviour so you can provide the full filename including extension for a PKCS#12 keystore as these commonly have the extension ‘.p12’. (and if you are using AMQP must have a ‘.p12’ extension).
For those migrating from earlier versions no action is needed to update the existing values, IBM MQ still supports a filename without an extension. The behaviour here is that first IBM MQ will look for a file that exists as if the value is the full filename. If MQ cannot find one then it reverts to the old behaviour and assumes the provided value is missing the ‘.kdb’ extension, automatically appending it for you.
Providing access to a keystore
Both PKCS#12 keystores and CMS keystores are secured as they contain sensitive data. To read the contents of a keystore IBM MQ needs to be provided a mechanism to access it. Prior to version 9.3 LTS the only mechanism was a stash file. This was a GSKit specific file created at keystore creation, or later using the -keydb -stashpw commands. It co-existed alongside the keystore and had the ‘.sth’ extension.
In IBM MQ 9.3 LTS as well as PKCS#12 support MQ also added in the ability to provide the keystore password directly to a queue manager or client application. For the queue manager this is done using the MQSC KEYRPWD attribute. For client applications you have 3 choices: the KeyRepoPassword field on the MQSCO structure, the MQKEYRPWD environment variable or the SSLKeyRepositoryPassword attribute on the SSL stanza of the client configuration file mqclient.ini.
Encrypting the keystore password
The password fields can accept the password as a plaintext password. However, this is not secure, to enable secure practices MQ added a password protection system you can use to encrypt passwords.
For the queue manager this is done for you automatically. When you provide a password to the KEYRPWD attribute IBM MQ automatically encrypts it using the initial key set as the MQSC INITKEY field. This has a default value that should be changed prior to setting the password.
For client applications the tool runmqicred has been provided to encrypt password prior to storing in any of the 3 options above. When running this tool, you can provide a file containing the initial key which the tool should use to encrypt the password. If you do not provide your own initial key, a default will be used.
If you do encrypt your password with a custom initial key, you must provide this same key to your application so IBM MQ can decrypt the password at runtime. This can be done using one of 3 options: The InitialKey fields on the MQCSP structure, the MQS_MQI_KEYFILE environment variable or the MQIInitialKeyFile attribute on the security stanza of the client configuration file mqclient.ini.
Benefits of PKCS#12 keystores.
Why use PKCS#12 keystores? In the end it is entirely your choice which format to use. There is currently no deprecation statement out for CMS keystores, and IBM MQ continues to support them. However, there is a gentle trend of moving to a standard format for keystores. IBM WebSphere liberty uses PKCS#12 as the default keystore type as of version 19.0.0.2.
Additionally, by using an industry standard keystore format you can take advantage of certificate management tools to manage your PKI estate.
For customers who also use IBM MQ’s AMQP functionality, you need to be aware that from IBM MQ 9.4 LTS a PKCS#12 keystore is mandatory, this blog post details why and action you should take.
For example…
As an example, here’s a very quick way to set up a queue manager and client application to use a PKCS#12 keystore and providing the password instead of a stash file. I’m going to use one keystore to keep the example short, but the process is the same for two keystores. I’ll also be connecting as a user called testuser that has been pre-authorized to a channel that has been pre-created.
$ cd /var/mqm/qmgrs/QM1/ssl
$ echo thisIsMyIn1t1alKey! > init.key # Create the initial key file
$ runmqakm -keydb -create -db key.p12 -pw wibble -type p12 # Create the keystore
$ runmqakm -cert -create -db key.p12 -pw wibble -dn CN=QMGR -label qmgr
$ runmqsc QM1 # Tell the queue manager to use the keystore
5724-H72 (C) Copyright IBM Corp. 1994, 2024.
Starting MQSC for queue manager QM1.
ALTER QMGR INITKEY('thisIsMyIn1t1alKey!') KEYRPWD('wibble') SSLKEYR('/var/mqm/qmgrs/QM1/ssl/key.p12') CERTLABL('qmgr')
1 : ALTER QMGR INITKEY('thisIsMyIn1t1alKey!') KEYRPWD('wibble') SSLKEYR('/var/mqm/qmgrs/QM1/ssl/key.p12') CERTLABL('qmgr')
AMQ8005I: IBM MQ queue manager changed.
refresh security type(SSL)
2 : refresh security type(SSL)
AMQ8560I: IBM MQ security cache refreshed.
end
3 : end
2 MQSC commands read.
No commands have a syntax error.
All valid MQSC commands were processed.
$ runmqicred -sf init.key # Encrypt the keystore password for the client.
Enter password:
******
<MQI>!2!BgDXWFLNcyZ7aINrXEF/q2yI2sr+CvE3arLJm/E8NqM=!X/0TKSMdEuZtjZmOUDk6Hg==
$ export MQKEYRPWD='<MQI>!2!BgDXWFLNcyZ7aINrXEF/q2yI2sr+CvE3arLJm/E8NqM=!X/0TKSMdEuZtjZmOUDk6Hg==' # Give the client the encrypted password
$ export MQS_MQI_KEYFILE=/var/mqm/qmgrs/QM1/ssl/init.key # Give the client the initial keyfile
$ /opt/mqm/samp/bin/amqssslc -m QM1 -c IN -x "localhost(1414)" -s ANY -k /var/mqm/qmgrs/QM1/ssl/key.p12
Sample AMQSSSLC start
Connecting to queue manager QM1
Using the server connection channel IN
on connection name localhost(1414).
Using SSL CipherSpec ANY
Using SSL key repository stem /var/mqm/qmgrs/QM1/ssl/key.p12
No OCSP configuration specified.
Connection established to queue manager QM1
Sample AMQSSSLC end
Conclusion
In conclusion, IBM MQ supports PKCS#12 keystores and the ability to provide a password to access the keystore instead of relying on stash files. This functionality is available in IBM MQ 9.3 LTS and above. It is your choice as users which format to use, and IBM MQ supports CMS and PKCS#12 keystores in tandem unless you are an AMQP user.
As always if there is a change or extension to the feature you wish to see then do not hesitate to raise an Aha idea to let us know!