Alpay
Alpay

Reputation: 1368

Nifi JMS input for Websphere MQ with TLS

I am trying to create a nifi flow with JMS input to connect to Websphere MQ, running on z/OS. I am able to successfully connect using JNDI (with .bindings file) if the queue manager is not protected with TLS. I get unsupported ciphersuite error when I switch to a secure queue manager:

Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2393;AMQ9771: SSL handshake failed. [1=java.lang.IllegalArgumentException[Unsupported ciphersuite SSL_RSA_WITH_AES_256_CBC_SHA256],3=10.24.98.154/10.24.98.154:457 (10.24.98.154),4=SSLSocket.createSocket,5=default]
    at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnection.java:2093)
    at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.connnectUsingLocalAddress(RemoteTCPConnection.java:870)
    at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.protocolConnect(RemoteTCPConnection.java:1294)
    at com.ibm.mq.jmqi.remote.impl.RemoteConnection.connect(RemoteConnection.java:892)
    at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSessionFromNewConnection(RemoteConnectionSpecification.java:416)
    at com.ibm.mq.jmqi.remote.impl.RemoteConnectionSpecification.getSession(RemoteConnectionSpecification.java:312)
    at com.ibm.mq.jmqi.remote.impl.RemoteConnectionPool.getSession(RemoteConnectionPool.java:146)
    at com.ibm.mq.jmqi.remote.api.RemoteFAP.jmqiConnect(RemoteFAP.java:1761)
    ... 40 common frames omitted
Caused by: java.lang.IllegalArgumentException: Unsupported ciphersuite SSL_RSA_WITH_AES_256_CBC_SHA256
    at sun.security.ssl.CipherSuite.valueOf(CipherSuite.java:228)
    at sun.security.ssl.CipherSuiteList.<init>(CipherSuiteList.java:79)
    at sun.security.ssl.SSLSocketImpl.setEnabledCipherSuites(SSLSocketImpl.java:2495)
    at com.ibm.mq.jmqi.remote.impl.RemoteTCPConnection.makeSocketSecure(RemoteTCPConnection.java:2084)
    ... 47 common frames omitted

I think the problem is to supply the -Dcom.ibm.mq.cfg.preferTLS=true variable to nifi process. I tried to add it into bootstrap.conf but it didn' t help.

Is there a any other way to supply -Dcom.ibm.mq.cfg.preferTLS=true variable into ibm jms client jar? I really stuck with this problem, so any help would be very beneficial. Thank you

Upvotes: 0

Views: 1250

Answers (1)

JoshMc
JoshMc

Reputation: 10642

The problem you are having is that IBM MQ classes for JMS (com.ibm.mq.allclient.jar) can work with both IBM Java JSSE and non-IBM (ex: Oracle) Java JSSE. Ciphersuite names are different between the two Java JSSE implementations. For the most part where Oracle follows the IETF naming standards and the prefix of the ciphersuite is TLS_, IBM replaces this with SSL_.


A table documenting how the IBM MQ SVRCONN channel CIPHERSPEC name maps to the IBM and Oracle Java JSSE ciphersuite name can be found in IBM's Knowledge center: IBM MQ > Developing applications > Developing JMS and Java applications > Using IBM MQ classes for JMS > Writing IBM MQ classes for JMS applications > Accessing IBM MQ features from an IBM MQ classes for JMS application > Using TLS with IBM MQ classes for JMS > TLS CipherSpecs and CipherSuites in IBM MQ classes for JMS

For example the CIPHERSPEC you provided TLS_RSA_WITH_AES_256_CBC_SHA256 has this entry in the table.

CipherSpec                      |Equivalent CipherSuite (IBM JRE) |Equivalent CipherSuite (Oracle JRE) |Protocol |FIPS 140-2 compatible |
--------------------------------+---------------------------------+------------------------------------+---------+----------------------|
TLS_RSA_WITH_AES_256_CBC_SHA256 |SSL_RSA_WITH_AES_256_CBC_SHA256  |TLS_RSA_WITH_AES_256_CBC_SHA256     |TLS v1.2 |yes                   |

You are running into two issues:


First, in order to tell the IBM MQ Classes for JMS that you want it to use the Oracle ciphersuite mapping you need to set the Java system property com.ibm.mq.cfg.useIBMCipherMappings to the value false (Note the default is true).

This can be done in your code:

System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");

or on the command line:

-Dcom.ibm.mq.cfg.useIBMCipherMappings=false

Second, when you use JMSAdmin to generate the binding file, it will by default will take the ciphersuite name you provide and "convert" it into the IBM ciphersuite name. So when you specified TLS_RSA_WITH_AES_256_CBC_SHA256 it converted it to SSL_RSA_WITH_AES_256_CBC_SHA256 in the resulting binding file.

To fix this you need to edit the JMSAdmin and look for a line like this:

$AMQJAVA -Dcom.ibm.msg.client.commonservices.log.outputName=$MQ_JAVA_DATA_PATH/log -Dcom.ibm.msg.client.commonservices.trace.outputName=$MQ_JAVA_DATA_PATH/trace -DMQ_JAVA_INSTALL_PATH=$MQ_JAVA_INSTALL_PATH com.ibm.mq.jms.admin.JMSAdmin $*

You will need to add -Dcom.ibm.mq.cfg.useIBMCipherMappings=false to the line line like this:

$AMQJAVA -Dcom.ibm.mq.cfg.useIBMCipherMappings=false -Dcom.ibm.msg.client.commonservices.log.outputName=$MQ_JAVA_DATA_PATH/log -Dcom.ibm.msg.client.commonservices.trace.outputName=$MQ_JAVA_DATA_PATH/trace -DMQ_JAVA_INSTALL_PATH=$MQ_JAVA_INSTALL_PATH com.ibm.mq.jms.admin.JMSAdmin $*

Fixing the first issue will allow IBM MQ Classes for JMS to use the Oracle ciphersuite mappings.

Fixing the second issue will allow the generation of a binding file that contains a proper Oracle ciphersuite name.


Currently the error returned is RC=2393 which means MQRC_SSL_INITIALIZATION_ERROR, this is because IBM MQ classes for Java thinks it should use IBM ciphersuite mappings and sends the SSL_RSA_WITH_AES_256_CBC_SHA256 ciphersuite name to the Oracle Java which then returns the error you are receiving, Unsupported ciphersuite SSL_RSA_WITH_AES_256_CBC_SHA256, because Oracle Java does not know of a ciphersuite by that name.

Note if you were to fix only one of the two issues, then then the IBM MQ classes for JMS would return RC=2400 which means MQRC_UNSUPPORTED_CIPHER_SUITE before even calling out to the Java JSSE.

Upvotes: 1

Related Questions