Reputation: 1368
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
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