1. This topic is about how to use
HERMESJMS over SSL enabled MQ
Channel – (no MA setup).
By Seri Charoensri 22 July 2012 (charoensri.seri@gmai.com)
With IBM MQ Provider: If you experience error below with JSSE, certification not found.
com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2397'
('MQRC_JSSE_ERROR').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:421)
at
com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6807)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6204)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:278)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6155)
1. Hermes runs on standard JDK, with that Hermes is using JSSE security – cacerts (CA
certificates store). Below we imported self-sign cert generated and extracted from
IKEYMAN.
IKEYMAN
3. C:Program Files (x86)Javajdk1.6.0_13jrelibsecuritycacerts (I just use the
default/provide truststore by JDK, you can use your truststore, if you like). Hermes will
check the MQ Server’s cert from this trustore.
Keytool
2. For self-sign cert from MQ, you will need to import the cert into cacerts keystore, so that
HERMES can hand-shake with MQ over SSL.
C:Program Files (x86)Javajdk1.6.0_13jrebin>keytool -import -trustcacerts -alias qm5
-file ..libsecurityQM12345-certQM5_cert.arm -keystore ..libsecuritycacerts
Enter keystore password: changeit (default JSSE CA keystore)
Owner: CN=qm5, C=US
Issuer: CN=qm5, C=US
Serial number: -54f5d8343411e1b8
Valid from: Fri Jul 20 21:14:59 EST 2012 until: Sun Jul 21 21:14:59 EST 2013
Certificate fingerprints:
MD5: 7A:2C:20:3A:CE:94:2B:44:F0:C4:65:C8:FD:A4:17:9F
SHA1: B5:D0:68:84:75:D2:6D:ED:61:AC:C6:32:87:F5:0C:69:28:AC:C0:6E
Signature algorithm name: MD5withRSA
Version: 3
Trust this certificate? [no]: y
Certificate was added to keystore
C:Program Files (x86)Javajdk1.6.0_13jrebin>
HERMES JMS setting
IBM MQ 7 Provider Lib: - don’t need all of those lib – I am lazy to pick just the jars required.
4. C:Program Files (x86)IBMWebSphere MQJavalibcom.ibm.mq.jar
C:Program Files (x86)IBMWebSphere MQJavalibcom.ibm.mq.jms.Nojndi.jar
C:Program Files (x86)IBMWebSphere MQJavalibcom.ibm.mq.soap.jar
C:Program Files (x86)IBMWebSphere MQJavalibcom.ibm.mqjms.jar
C:Program Files (x86)IBMWebSphere MQJavalibcommonservices.jar
C:Program Files (x86)IBMWebSphere MQJavalibconnector.jar
C:Program Files (x86)IBMWebSphere MQJavalibdhbcore.jar
C:Program Files (x86)IBMWebSphere MQJavalibfscontext.jar
C:Program Files (x86)IBMWebSphere MQJavalibjms.jar
C:Program Files (x86)IBMWebSphere MQJavalibjndi.jar
C:Program Files (x86)IBMWebSphere MQJavalibjta.jar
C:Program Files (x86)IBMWebSphere MQJavalibldap.jar
SSLCipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA
channel qm5_ch1
hostName 127.0.0.1
port 1418
queueManager QM5
transportType 1
IBM MQ setup
On the MQ we have “TRIPLE_DES_SHA_SA” SSL setup – no client SSL (SSLCAUTH) required.
“Authentication of Parties initiating connections: - Optional”. In short, we trust the MQ server’s SSL
cert only, no Mutual Authentication setup for now. I will show you how to do MA below.
5. NOTE: we have not set the SSLCAUTH to be required, or lock down the DN name specification to
only allow clients with the DN name come through.
Test result
We success fully retrieve data over SSL-enabled channel.
6. This topic is about how to use
HERMESJMS over SSL enabled MQ
Channel – (with MA setup).
With MA, the client (HERMESJMS in this case) will need to provide Client’sSSL to MQ server for
Client Auth (SSLCAUTH-Required)
Setup a new SVRCONN channel for MA with DN spec.
7. Need to create Client’s Keystore - hermesclientkey.jks
NOTE: we use the default JDK truststore –cacerts to hold MQ SSL Cert (above). Alternatively, you
could create your TrustStore and manage MQ Cert separately.
We will need create Hermes keystore since no default provided.
default No default. * javax.net.ssl.keyStore system property
keystore Note that the value NONE may be specified. This setting
is appropriate if the keystore is not file-based (for
example, it resides in a hardware token).
default No default. * javax.net.ssl.keyStorePassword system
keystore property
password
default No default. * javax.net.ssl.keyStoreProvider system
keystore property
provider
default KeyStore.getDefaultType() * javax.net.ssl.keyStoreType system property
keystore
type
default jssecacerts, if it exists. * javax.net.ssl.trustStore system property
truststore Otherwise, cacerts
default No default. * javax.net.ssl.trustStorePassword system
truststore
password
8. property
default No default. * javax.net.ssl.trustStoreProvider system
truststore property
provider
default KeyStore.getDefaultType() * javax.net.ssl.trustSt
truststore
type
Extract and Import our new Client Self-signed certs to MQ’s Keystore (CMS/KDB), so that MQ can
trust our new client cert (this is self-sign, not signed by well-known CA certs that come with the
default keystore)
HERMESJMS SETUP TO use the new personal keystore
The HERMESJMSkeystore.jks holds its certificate which will be exchange (MA) with the MQ server.
Since this is a self-sign, we have given the key to MQ servers’s keystore (CMS KDB)
javax.net.ssl.keyStore = “C:/seri/HermesJMS/hermes client key/HERMESJMSkeystore.jks”
javax.net.ssl.keyStorePassword = “MySecretSorry”
9. We will use Default SunJSSE provider!! – you can use IBM or BouncyCastle, etc if you like if you need
higher cipher e.g AES128. If you do so, don’t for get to add the Security Provider jars to
C:Program Files (x86)Javajdk1.6.0_13jrelibext then “Add” the new security.provider to the
java.secuirty file.
#java.security provider
# List of providers and their preference orders (see above):
#
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.8=sun.security.smartcardio.SunPCSC
security.provider.9=sun.security.mscapi.SunMSCAPI
Syntax:
% java -Djavax.net.ssl.keyStore=keystore
-Djavax.net.ssl.keyStorePassword=password Server
% java -Djavax.net.ssl.trustStore=truststore
-Djavax.net.ssl.trustStorePassword=trustword Client
Example
C:seriHermesJMSbinHermes.bat
start "HermesJMS" "%JAVA_HOME%binjavaw" -XX:NewSize=256m -Xmx1024m
-Djavax.net.ssl.keyStore="C:seriHermesJMShermes client keyhermesclientkey.jks"
-Djavax.net.ssl.keyStorePassword="secretPWD!"
-Djavax.net.debug="ssl,keymanager"
-Dhermes.home="%HERMES_HOME%" %HERMES_OPTS%
-Dlog4j.configuration="file:%HERMES_HOME%binlog4j.props"
-Dsun.java2d.noddraw=true
-Dhermes="%HERMES_CONFIG%hermes-config.xml"
-Dhermes.libs="%HERMES_LIBS%" hermes.browser.HermesBrowser
10. NOTE: again, I simply leverage JDK’s truststore “cacerts” in ..libsecurity
NOTE: HermesJMS will now start with the keystore hermesclientkey.jks for it to authenticate
itself to MQ Server.
Test result with MA – no SSLPeer restriction
With MQ Sever’s SSLPeer restriction:
11. Hermes will fail since our CN is NOT “aa” – but cn=hermesclientkey
12. com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2059'
('MQRC_Q_MGR_NOT_AVAILABLE').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:421)
at
com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:6807)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:6204)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:278)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6155)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:115)
at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:198)
at hermes.impl.jms.ConnectionManagerSupport.createConnection(ConnectionManagerSupport.java:122)
at hermes.impl.jms.ConnectionManagerSupport.createConnection(ConnectionManagerSupport.java:92)
at hermes.impl.jms.ConnectionSharedManager.reconnect(ConnectionSharedManager.java:81)
at hermes.impl.jms.ConnectionSharedManager.connect(ConnectionSharedManager.java:91)
at hermes.impl.jms.ConnectionSharedManager.getConnection(ConnectionSharedManager.java:104)
at hermes.impl.jms.ConnectionSharedManager.getObject(ConnectionSharedManager.java:142)
at hermes.impl.jms.ThreadLocalSessionManager.connect(ThreadLocalSessionManager.java:190)
at hermes.impl.jms.ThreadLocalSessionManager.getSession(ThreadLocalSessionManager.java:570)
at hermes.impl.jms.AbstractSessionManager.getDestination(AbstractSessionManager.java:460)
13. at hermes.impl.DefaultHermesImpl.getDestination(DefaultHermesImpl.java:367)
at hermes.browser.tasks.BrowseDestinationTask.invoke(BrowseDestinationTask.java:141)
at hermes.browser.tasks.TaskSupport.run(TaskSupport.java:175)
at hermes.browser.tasks.ThreadPool.run(ThreadPool.java:170)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2059;AMQ9204: Connection to host '127.0.0.1(1418)' rejected.
[1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2059;AMQ9643: Remote SSL peer name error for channel 'qm5_ch3_ma'.
[3=qm5_ch3_ma]],3=127.0.0.1(1418),5=RemoteConnection.analyseErrorSegment]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1809)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:336)
... 20 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2059;AMQ9643: Remote SSL peer name error for channel 'qm5_ch3_ma'.
[3=qm5_ch3_ma]
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.analyseErrorSegment(RemoteConnection.java:4223)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.receiveTSH(RemoteConnection.java:2822)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.initSess(RemoteConnection.java:1399)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.connect(RemoteConnection.java:1078)
at com.ibm.mq.jmqi.remote.internal.system.RemoteConnectionPool.getConnection(RemoteConnectionPool.java:338)
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1488)
... 21 more
14. Adjust SSLPeer to be the same as the client cert’s DN name – this should allow Hermes to be
successful authenticated with MA, plus DN validation.
Test result with MA and DN lock-down on the MQ Server side.
Also Hermes as a JMS client can request MQ Cert’s DN for
SSLPeer validation. That’s Q Client can check the MQ server SSL Cert’ DN name. Below is the MQ
Server cert labled: ibmwebspheremq<QMGR> ie.”ibmwebspheremqqm5” with CN = qm5
15.
16. Hermes will need to setup SSLPeer (MQ server’s cert) to check for “cn=qm5”
SSLCipherSuite SSL_RSA_WITH_3DES_EDE_CBC_SHA
channel qm5_ch3_ma
hostName 127.0.0.1
port 1418
queueManager QM5
transportType 1
SSLPeerName cn=qm5
17. Try the “cn=qm5-bad-PEERNAME”
com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2398'
('MQRC_SSL_PEER_NAME_MISMATCH').
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2398;AMQ9204: Connection to host '127.0.0.1(1418)' rejected.
[1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2398;AMQ9636: SSL distinguished name does not match peer name, channel '?'.
[4=CN=qm5, C=US]],3=127.0.0.1(1418),5=RemoteTCPConnection.protocolConnect]
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2398;AMQ9636: SSL distinguished name does not match peer name, channel '?'.
[4=CN=qm5, C=US]
24. com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2'
('MQCC_FAILED') reason '2397' ('MQRC_JSSE_ERROR').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:223)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:421)
at
com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQCon
nectionFactory.java:6807)
at
com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConne
ctionFactory.java:6204)
at
com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryI
mpl.java:278)
at
com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:615
5)
at
com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactor
y.java:115)
at
com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:
198)
at
hermes.impl.jms.ConnectionManagerSupport.createConnection(ConnectionManagerSupport.java:1
22)
at
hermes.impl.jms.ConnectionManagerSupport.createConnection(ConnectionManagerSupport.java:9
2)
at
hermes.impl.jms.ConnectionSharedManager.reconnect(ConnectionSharedManager.java:81)
at hermes.impl.jms.ConnectionSharedManager.connect(ConnectionSharedManager.java:91)
at
hermes.impl.jms.ConnectionSharedManager.getConnection(ConnectionSharedManager.java:104)
25. at
hermes.impl.jms.ConnectionSharedManager.getObject(ConnectionSharedManager.java:142)
at
hermes.impl.jms.ThreadLocalSessionManager.connect(ThreadLocalSessionManager.java:190)
at
hermes.impl.jms.ThreadLocalSessionManager.getSession(ThreadLocalSessionManager.java:570)
at
hermes.impl.jms.AbstractSessionManager.getDestination(AbstractSessionManager.java:460)
at hermes.impl.DefaultHermesImpl.getDestination(DefaultHermesImpl.java:367)
at hermes.browser.tasks.BrowseDestinationTask.invoke(BrowseDestinationTask.java:141)
at hermes.browser.tasks.TaskSupport.run(TaskSupport.java:175)
at hermes.browser.tasks.ThreadPool.run(ThreadPool.java:170)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9204: Connection to host
'127.0.0.1(1418)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2397;AMQ9771: SSL
handshake failed. [1=java.net.SocketException[java.security.NoSuchAlgorithmException: Error
constructing implementation (algorithm: Default, provider: SunJSSE, class:
com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)],3=Seri-THINK/127.0.0.1:1418 (Seri-
THINK),4=SSLSocket.createSocket,5=default]],3=127.0.0.1(1418),5=RemoteTCPConnection.makeSoc
ketSecure]
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1809)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:336)
... 20 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2397;AMQ9771: SSL handshake failed.
[1=java.net.SocketException[java.security.NoSuchAlgorithmException: Error constructing
implementation (algorithm: Default, provider: SunJSSE, class:
com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)],3=Seri-THINK/127.0.0.1:1418 (Seri-
THINK),4=SSLSocket.createSocket,5=default]
at
com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnectio
n.java:1621)
at
com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.connnectUsingLocalAddress(RemoteTCPC
onnection.java:618)
26. at
com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.j
ava:935)
at
com.ibm.mq.jmqi.remote.internal.system.RemoteConnection.connect(RemoteConnection.java:1075
)
at
com.ibm.mq.jmqi.remote.internal.system.RemoteConnectionPool.getConnection(RemoteConnectio
nPool.java:338)
at com.ibm.mq.jmqi.remote.internal.RemoteFAP.jmqiConnect(RemoteFAP.java:1488)
... 21 more
Caused by: java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing
implementation (algorithm: Default, provider: SunJSSE, class:
com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
at javax.net.ssl.DefaultSSLSocketFactory.throwException(SSLSocketFactory.java:179)
at javax.net.ssl.DefaultSSLSocketFactory.createSocket(SSLSocketFactory.java:199)
at
com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnectio
n.java:1614)
... 26 more
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm:
Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)
at java.security.Provider$Service.newInstance(Provider.java:1245)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:220)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:147)
at javax.net.ssl.SSLContext.getInstance(SSLContext.java:125)
at javax.net.ssl.SSLContext.getDefault(SSLContext.java:68)
at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:102)
at
com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.chooseSocketFactory(RemoteTCPConnecti
on.java:2073)
27. at
com.ibm.mq.jmqi.remote.internal.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnectio
n.java:1604)
... 26 more
Caused by: java.security.NoSuchProviderException: no such provider: sun.security.provider.Sun11
at sun.security.jca.GetInstance.getService(GetInstance.java:66)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:190)
at java.security.Security.getImpl(Security.java:662)
at java.security.KeyStore.getInstance(KeyStore.java:632)
at
com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.getDefaultKeyManager(DefaultSSLContextImpl.ja
va:145)
at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.<init>(DefaultSSLContextImpl.java:40)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.jav
a:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at java.security.Provider$Service.newInstance(Provider.java:1221)
... 33 more