Recently I've been migrated to IBM MQ v8 to IBM MQ v9 (v9.1.2.0 specifically). I used SSL to communicate with the broker. So as per Deprecated CipherSpecs document, IBM has deprecated number of cipher suites that came up with MQ 8 and seems all of the cipher suites I've been using, have been deprecated with v9 upward. Therefore, I've implemented new TLS cipher suites to work with my application which runs on a Oracle JVM (version 1.8.0_211). Ever since I'm getting following exception in the application though;
com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2400'.
at com.ibm.mq.MQManagedConnectionJ11.constructMQCD(MQManagedConnectionJ11.java:1437)
at com.ibm.mq.MQManagedConnectionJ11.constructCNO(MQManagedConnectionJ11.java:1537)
at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:221)
... (Omitted the rest)
When I dig about the reason, found that's a problem with IBM MQ cipher suites and Oracle JRE cipher suite name mismatch. But I did refer TLS CipherSpecs and CipherSuites in IBM MQ classes for JMS document to map cipher suite names. I used some of Equivalent CipherSuite (Oracle JRE) column values in my application that already available in IBM MQ as well. But still getting the issue.
After I found this answer that advises to add this -Dcom.ibm.mq.cfg.useIBMCipherMappings=false
argument to IBM MQ's JRE (As I understand). This might allow IBM MQ to use Oracle complied cipher suite names. My question is,
- How to add this JVM argument
-Dcom.ibm.mq.cfg.useIBMCipherMappings=false
to IBM MQ JRE?
This Problem Connecting a Java Client (JMS) to a IBM MQ question suggests that the same parameter needed to be added to the application as a system property System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false")
, but it didn't make any different.
Java connection to WMQ 8 question also states the same solution, but doesn't mention how to add this JVM argument to IBM MQ.
Update 1
I did some research about how to add a JVM argument to IBM MQ. But I was only able to find a solutions for Websphere application server.
CipherSuite I'm currently using in the application is;
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (Oracle JRE complied)
IBM MQ has respective;
ECDHE_ECDSA_AES_128_CBC_SHA256 (IBM MQ complied)
Update 2
After creating a key.kdb
file with ikeyman
tool with the stash
option queue manager can successfully read the certificates in it. Also, I've included a self-signed certificate labeled with ibmwebspheremq<lowercase_queue_manage_name>
. But now I'm getting a different exception in the client side;
Exception in thread "main" com.ibm.mq.MQException: MQJE001: Completion Code '2', Reason '2059'.
at com.ibm.mq.MQManagedConnectionJ11.<init>(MQManagedConnectionJ11.java:255)
at com.ibm.mq.MQClientManagedConnectionFactoryJ11._createManagedConnection(MQClientManagedConnectionFactoryJ11.java:450)
at com.ibm.mq.MQClientManagedConnectionFactoryJ11.createManagedConnection(MQClientManagedConnectionFactoryJ11.java:487)
at com.ibm.mq.StoredManagedConnection.<init>(StoredManagedConnection.java:97)
and in the MQ log I can find this entry;
AMQ9637E: Channel is lacking a certificate.
with some explanation.
After working for while, I was able resolve this issue. Since the beginning I had this certificate configuration issue in the application side. Even after creating
self-signed
certificate labeled afteribmwebspheremq<queue_manager_name>
and shared the extracted certificates with the client application usingikeyman
tool,AMQ9637E: Channel is lacking a certificate.
occurred.In a nutshell, to resolve this issue entirely, I did the following;
Update the client MQ dependency to
com.ibm.mq.allclient:v9.1.2.0
. If you're using maven, use following dependency (MQC91: IBM MQ Clients).Now, if the application runs on an Oracle JVM, we should convince the MQ client lib to use Oracle JVM complied cipher suite names. To do that, either add this
-Dcom.ibm.mq.cfg.useIBMCipherMappings=false
as a JVM flag or add thisSystem.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false")
as a system property.Select a appropriate cipher suite to communicate with the MQ. This TLS CipherSpecs and CipherSuites in IBM MQ classes for JMS document would be helpful as IBM has deprecated number of weak cipher specs IBMMQ 9 onwards.
I would suggest to use
ECDHE_*
cipher specs as they provide Ephemeral Keys to maintain Forward Secrecy.Then, using
ikeyman
GUI tool, I created aself-signed
certificate labeled afteribmwebspheremq<queue_manager_name>
name and instead of extracting the.arm
file, I export the certificate as.jks
files. Bothkeystore.jks
andtruststore.jks
files exported from the same certificate. After, attached them to the application using system properties;With this configuration, SSL handshake issue went away, but the IBM MQ was still asking for user authentication with a user name and password. In order to provide them, should add these properties to
MQEnvironment
,These credentials were system credentials in my case.
If you simply want to skip user authentication like this, you can update IBMMQ config to skip credential check using
runmqsc
CLI tool like this (Refer this Turning on connection authentication on a queue manager document),Note that
CHCKCLNT
value needed to set asOPTIONAL
to ignore client user credential check. IBM MQ should start to work with the client application whilst SSL enabled after these configurations.Kudos to @JoshMc for the support to resolve this issue.