Most discussions on using SSL with WMQ Java applications (using the WMQ Classes for Java) talk about using the javax.net.ssl.keyStore etc. Java System Properties to specify a certificate store and password.
This works well for most applications.
However, there are a few limitations to this approach:
- The SSL context is initialised only once – the first time it is used.
If the path/password is incorrect, the JVM must be terminated before trying again. - Debugging is only available through using javax.net.debug system property.
This produces a large amount of output on the console. - Only one certificate store can be used per JVM.
You might want to use different certificates to connect to different queue managers.
So, this post has the starting point for an alternative.
Simple example class
The following class connects to a queue manager, and queries the description.
The main thing missing is exception handling.
However, if you get a failure, it does show how you can get useful exceptions from this approach rather than just 2393 MQRC_SSL_INITIALIZATION_ERROR
.
package hursleyonwmq; // Standard Java API imports import java.io.FileInputStream; import java.util.Hashtable; // Standard Java SSL API imports import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; // WMQ imports import com.ibm.mq.MQC; import com.ibm.mq.MQQueueManager; /** * Simple command line class to create an SSL connection * to a queue manager, with the WMQ Base Java classes. * @author hursleyonwmq blogger * @see https://hursleyonwmq.wordpress.com */ public class WmqSslTest { /** * Main method * Example MQSC to define SVRCONN: * DEF CHL(TEST.SSL.CHL) CHLTYPE(SVRCONN) SSLCIPH(RC4_MD5_US) * @param args Unused * @throws Exception No exception handling */ public static void main(String[] args) throws Exception { // Queue manager details String qmgrName = "TEST.SSL"; Hashtable props = new Hashtable(); props.put(MQC.CHANNEL_PROPERTY, "TEST.SSL.CHL"); props.put(MQC.HOST_NAME_PROPERTY, "localhost"); props.put(MQC.PORT_PROPERTY, new Integer(1414)); // SSL details props.put(MQC.SSL_CIPHER_SUITE_PROPERTY, "SSL_RSA_WITH_RC4_128_MD5"); String keyStorePath = "keystore.jks"; String trustStorePath = "keystore.jks"; String password = "passw0rd"; // Create a keystore object for the keystore KeyStore keyStore = KeyStore.getInstance("JKS"); // Open our file and read the keystore FileInputStream keyStoreInput = new FileInputStream(keyStorePath); try { keyStore.load(keyStoreInput, password.toCharArray()); } finally { keyStoreInput.close(); } // Create a keystore object for the truststore KeyStore trustStore = KeyStore.getInstance("JKS"); // Open our file and read the truststore (no password) FileInputStream trustStoreInput = new FileInputStream(trustStorePath); try { trustStore.load(trustStoreInput, null); } finally { trustStoreInput.close(); } // Create a default trust and key manager TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); // Initialise the managers trustManagerFactory.init(trustStore); keyManagerFactory.init(keyStore,password.toCharArray()); // Get an SSL context. For more information on providers see: // http://www.ibm.com/developerworks/library/j-ibmsecurity.html // Note: Not all providers support all CipherSuites. SSLContext sslContext = SSLContext.getInstance("SSL_TLS"); System.out.println("SSLContext provider: " + sslContext.getProvider().toString()); // Initialise our SSL context from the key/trust managers sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); // Get an SSLSocketFactory to pass to WMQ SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); // Set the socket factory in our WMQ parameters props.put(MQC.SSL_SOCKET_FACTORY_PROPERTY, sslSocketFactory); // Connect to WMQ MQQueueManager qmgr = new MQQueueManager(qmgrName, props); try { // Query the description String desc = qmgr.getDescription(); // Output the description System.out.println("Queue Manager DESCR: \"" + desc + "\""); } finally { qmgr.disconnect(); } } }
3 comments
Comments feed for this article
March 9, 2007 at 12:17 pm
protocol7 » Blog Archive » links for 2007-03-09
[…] Custom SSLSocketFactory with WMQ Base Java (tags: wmq SSL ibm websphere jsse) […]
June 25, 2007 at 4:15 pm
WMQ Explorer and SSL « betaalfa
[…] making it possible to use multiple key and trust stores and easier configuration on top of that. An example of an custom SSLSocketFactory was published by Peter Broadhurst on the a Hursley view on WebSphere […]
May 31, 2008 at 12:01 pm
protocol7 » Blog Archive » Custom SSL factory
[…] providing a custom SSL socket factory. WebSphere MQ is an example of such an API. As described in this post by Peter Broadhurst, you can quite easily provide such a custom socket factory with the benefit of getting much […]