From WebSphere MQ V5.3, WebSphere MQ base Java clients and WebSphere MQ JMS connections using TRANSPORT(CLIENT) support Secure Sockets Layer (SSL) encryption. SSL provides communication encryption, authentication and message integrity. It is typically used to secure communications between any two peers on the public internet or within an intranet.
WebSphere MQ classes for Java uses Java Secure Socket Extension (JSSE) to handle SSL encryption, and so requires a JSSE provider. J2SE v1.4 JVMs have a JSSE provider built-in. Details of how to manage and store certificates can vary from provider to provider. For information about this, refer to your JSSE provider's documentation.
This section assumes your JSSE provider is correctly installed and configured, and suitable certificates have been installed and made available to your JSSE provider.
To enable SSL encryption on a ConnectionFactory, use JMSAdmin to set the SSLCIPHERSUITE property to a CipherSuite supported by your JSSE provider. This must match the CipherSpec set on the target channel. However, CipherSuites are distinct from CipherSpecs and so have different names. Appendix H, SSL CipherSuites supported by WebSphere MQ contains a table mapping the CipherSpecs supported by WebSphere MQ to their equivalent CipherSuites as known to JSSE. Additionally, the named CipherSuite must be supported by your JSSE provider. For more information about CipherSpecs and CipherSuites with WebSphere MQ, see the WebSphere MQ Security book.
For example, to set a QueueConnectionFactory to connect to an SSL-enabled SVRCONN channel using a CipherSpec of RC4_MD5_EXPORT, issue the following command to JMSAdmin:
ALTER QCF(my.qcf) SSLCIPHERSUITE(SSL_RSA_EXPORT_WITH_RC4_40_MD5)
This can also be set from a program, using the setSSLCipherSuite() method on MQConnectionFactory.
For convenience, if a CipherSpec is specified on the SSLCIPHERSUITE property, JMSAdmin will attempt to map the CipherSpec to an appropriate CipherSuite and issue a warning. Note that this attempt to map is not made if the property is specified by a program.
A JMS application can ensure that it has connected to the correct queue manager, by specifying a distinguished name (DN) pattern. The connection will only succeed if the queue manager presents a DN which matches the pattern. For more details of the format of this pattern, refer to the WebSphere MQ Security book or the WebSphere MQ Script (MQSC) Command Reference.
The DN is set using the SSLPEERNAME property of ConnectionFactory. For example, the following JMSAdmin command sets the ConnectionFactory to expect the queue manager to identify itself with a Common Name beginning "QMGR." with at least two Organizational Unit names, the first of which must be "IBM" and the second "WEBSPHERE":
ALTER QCF(my.qcf) SSLPEERNAME(CN=QMGR.*, OU=IBM, OU=WEBSPHERE)
Note that checking is case-insensitive, and that semicolons can be used in place of the commas. This can also be set from a program, using the setSSLPeerName() method on MQConnectionFactory. If this property is not set, no checking is performed on the Distinguished Name supplied by the queue manager. This property is ignored if no CipherSuite is set.
It is common to use a certificate revocation list (CRL) to manage revocation of certificates that have become untrusted. These are typically hosted on LDAP servers; and JMS allows an LDAP server to be specified for CRL checking under Java 2 v1.4 or later. The following JMSAdmin example directs JMS to use a CRL hosted on an LDAP server named crl1.ibm.com:
ALTER QCF(my.qcf) SSLCRL(ldap://crl1.ibm.com)
If your LDAP server is not running on the default port of 389, the port can be specified by appending a colon and the port number to the hostname. If the certificate presented by the queue manager is present in the CRL hosted on crl1.ibm.com, the connection will not complete. To avoid single-point-of-failure, JMS allows multiple LDAP servers to be supplied, by supplying a space-delimited list of ldap servers. For example:
ALTER QCF(my.qcf) SSLCRL(ldap://crl1.ibm.com ldap://crl2.ibm.com)
When multiple LDAP servers are specified, JMS will try each one in turn until it finds a server with which it can successfully verify the queue manager's certificate. Each server must contain identical information.
A string of this format can be supplied by a program on the MQConnectionFactory.setSSLCertStores() method. Alternatively, the application can create one or more java.security.cert.CertStore objects and place these in a suitable Collection object, and supply this Collection to the setSSLCertStores() method. In this way, the application can customize CRL checking. Please refer to your JSSE documentation for details on constructing and using CertStore objects.
The certificate presented by the queue manager when a connection is
being set up is validated as follows:
If this was the last CertStore in the Collection, or if the Collection
contains no CertStore objects, the search process has failed and the
connection request will fail with reason code
MQRC_SSL_CERT_STORE_ERROR.
The Collection object determines the order in which CertStores are
used.
If your application uses setSSLCertStores() to set a Collection of CertStore objects, the MQConnectionFactory can no longer be bound into a JNDI namespace. Attempting to do so will cause an Exception. If the sslCertStores property is not set, no revocation checking is performed on the certificate provided by the queue manager. This property is ignored if no CipherSuite is set.
You might want to customize other aspects of the SSL connection for an application. For example, you might want to initialize cryptographic hardware; or change the KeyStore and TrustStore in use. To do this, the application should first create a javax.net.ssl.SSLSocketFactory instance customized accordingly. Please refer to your JSSE documentation for information on how to do this as the customizable features vary from provider to provider. Once a suitable SSLSocketFactory has been obtained, use the MQConnectionFactory.setSSLSocketFactory() method to congure JMS to use the customized SSLSocketFactory.
If your application uses setSSLSocketFactory() to set a customized SSLSocketFactory, the MQConnectionFactory can no longer be bound into a JNDI namespace. Attempting to do so will cause an Exception. If this property is not set, the default SSLSocketFactory will be used; please refer to your JSSE documentation for details on the behavior of the default SSLSocketFactory. This property is ignored if no CipherSuite is set.