|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
What is the point of com.ibm.mq.cfg.useIBMCipherMappings |
« View previous topic :: View next topic » |
Author |
Message
|
RogerLacroix |
Posted: Tue Sep 17, 2019 1:09 pm Post subject: What is the point of com.ibm.mq.cfg.useIBMCipherMappings |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
All,
The JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings was introduced in MQ V7.0.1.13, V7.1.0.7, V7.5.0.5 and V8.0.0.2 (and is in MQ v9.0 and v9.1).
I thought I understood its purposed but I was reading the MQ Knowledge Center (again) and I think I misunderstood it or really don't understand it. The MQ Knowledge Center says for the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings:
Quote: |
true
Use the IBM Java CipherSuite to IBM MQ CipherSpec mappings. This value is the default value.
false
Use the Oracle CipherSuite to IBM MQ CipherSpec mappings. |
In my Java/MQ programs, I followed the rules laid out here:
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.dev.doc/q031220_.htm
which basically says use the CipherSuites from the tables here:
https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.1.0/com.ibm.mq.dev.doc/q113210_.htm
I created a 3 column table in my Java/MQ applications that presents the CipherSpec to the user and use the CipherSuite from the columns 2 or 3 depending on if they are running on an IBM JRE or Oracle JRE. Everything seemed fine.
i.e.
Code: |
if (System.getProperty("java.vendor").toLowerCase().indexOf("ibm") != -1)
// IBM JRE - use CipherSuite from column 2
else
// Oracle JRE - use CipherSuite from column 3 |
I'm getting people emailing me about setting up UFM (open source project), using SSL/TLS and setting the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings. People are emailing me with:
(1) Not setting any value for the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings and using Oracle JRE
(2) Setting the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings to true and using Oracle JRE
(3) Setting the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings to false and using IBM JRE
If the code followed the rules from the first link (Enabling TLS in IBM MQ classes for Java) then what is the purpose of the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings?
What exactly does the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings do?
Is it simply a way to not have a 3 column table in your program but rather 2 columns, i.e. CipherSpec and one CipherSuite, and the JVM environment variable com.ibm.mq.cfg.useIBMCipherMappings is simply telling the MQ Client library which CipherSuite column (IBM JRE or Oracle JRE) that will be used, hence, the MQ Client library will have a lookup table to convert the CipherSuite to the appropriate value?
What happens when someone gets it backwards (see points #1, 2 & 3 above)? Will it work or will the program get an MQ Reason Code of 2397?
Regards,
Roger Lacroix
Capitalware Inc. _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
RogerLacroix |
Posted: Wed Sep 18, 2019 10:37 am Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
All,
Here's what I posted to the MQ ListServer.
hughson wrote: |
Tim Zielke has subsequently raised another RFE to request IBM at least make a best effort on choosing the correct mapping |
Yup, I voted for it earlier this year.
tczielke wrote: |
If it is an IBM JRE, use com.ibm.mq.cfg.useIBMCipherMappings=true (or don't set it, as true is the default)
If it is an Oracle JRE, use com.ibm.mq.cfg.useIBMCipherMappings=false |
I thought the MQ Client library did some sort of conversion of the CipherSuite name to make it idiot proof for developers but that is not so.
A fellow MQ lister contacted me offline. We exchanged emails and he did some testing. From the tests, if the developer gets it backwards (see my previous points # 1, 2 & 3) then MQ immediately returns reason code of 2400 (MQRC_UNSUPPORTED_CIPHER_SUITE). The MQ Client library appears to have a list that is checked and if the CipherSuite is not on the list then it is immediately rejected. It does not even attempt the connection.
Now the reason I think the MQ Client library has 2 hard-coded CipherSuite lists (IBM & non-IBM) rather than interrogating the JRE for CipherSuites, is because of the results from 1 of the 8 tests he did (4 against IBM JRE and 4 against Oracle JRE).
- IBM JRE with JVM environment variable of com.ibm.mq.cfg.useIBMCipherMappings set to true:
-> CipherSuite: SSL_RSA_WITH_AES_256_CBC_SHA256 worked as expected
- IBM JRE with JVM environment variable of com.ibm.mq.cfg.useIBMCipherMappings set to false:
-> CipherSuite: TLS_RSA_WITH_AES_256_CBC_SHA256 unexpectedly worked but should have not worked if the MQ Client library interrogated the IBM JRE
So the JVM environment variable of com.ibm.mq.cfg.useIBMCipherMappings is required, even though it makes absolutely no sense. Someone at IBM over thought the situation. The simplest way to determine if the MQ Client library is running on an IBM JRE is to do:
Code: |
if (System.getProperty("java.vendor").toLowerCase().indexOf("ibm") != -1)
// IBM JRE
else
// not IBM JRE |
I'm just sitting here scratching my head. Ok. I was on vacation for a while in sunny California and maybe my brain is fried. I seriously don't get it. The JVM environment variable of com.ibm.mq.cfg.useIBMCipherMappings doesn't do anything other than a pre-check of the CipherSuites that are known to the MQ Client library. So basically, JVM environment variable of com.ibm.mq.cfg.useIBMCipherMappings is telling MQ Client library which CipherSuite list to check. Duh! IBM could figure this out in the MQ Client library?
Given that I get a lot of emails from users regarding the use of various open source projects I have and using SSL/TLS, I think there is a far, far simpler solution to this problem. I will do some testing first, but the simple solution is to put the following code snippet at the VERY beginning of the main() method of every Java application:
Code: |
if (System.getProperty("java.vendor").toLowerCase().indexOf("ibm") != -1)
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "true");
else
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false"); |
If the MQ Client library cannot figure out which JRE the application is running in, the above snippet of code will do it for you and set the required JVM environment variable. Hence, you do not need to remember to externally set the JVM environment variable in a script or batch shell.
Regards,
Roger Lacroix
Capitalware Inc. _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
hughson |
Posted: Wed Sep 18, 2019 6:46 pm Post subject: |
|
|
 Padawan
Joined: 09 May 2013 Posts: 1959 Location: Bay of Plenty, New Zealand
|
What about the mix of JRE vendor and JSSE? It's the JSSE in use that is important and not the JRE as has been discussed on the list-server.
Cheers,
Morag _________________ Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software |
|
Back to top |
|
 |
RogerLacroix |
Posted: Thu Sep 19, 2019 8:52 am Post subject: |
|
|
 Jedi Knight
Joined: 15 May 2001 Posts: 3264 Location: London, ON Canada
|
hughson wrote: |
What about the mix of JRE vendor and JSSE? It's the JSSE in use that is important and not the JRE as has been discussed on the list-server. |
True. There are 4 possible combinations:
(1) Oracle JRE and Oracle JSSE
(2) IBM JRE and IBM JSSE
(3) IBM JRE with Oracle JRE implementation and IBM JSSE - as referred to by IBM's response in your RFE
(4) Oracle JRE and IBM JSSE - I find this one extremely highly unlikely
As per my post on the MQ List Server @ 6:44PM EST, the code would be:
Code: |
boolean ibmJSSE = false;
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
String[] availableCiphers = ssf.getSupportedCipherSuites();
for (String cipher : availableCiphers)
{
if ("SSL_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA".equals(cipher))
ibmJSSE = true;
}
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", (ibmJSSE ? "true" : "false")); |
This code will get all available CipherSuites from whatever JSSE that the JRE is using then look for an IBM CipherSuite from TLS v1.2.
As I said at the bottom of the email:
RogerLacroix wrote: |
"SSL_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" is a TLS v1.2 CipherSuite. Hence, when future versions of TLS are released, the code can be updated to test for the latest CipherSuite. And if you wanted to supported older JREs then enhance the "if" to have many conditions testing for older CipherSuites.
This shit isn't that complicated even though IBM appears to be trying to make it that way. On my main development Windows PC, I have 13 JDKs and 18 JREs installed. Oracle: 10 JDKs and 10 JREs, IBM: 1 JDK and 6 JREs, AdoptOpenJDK: 2 JDKs and 2 JREs. To test against a different JDK/JRE, it is as simple as updating the batch file to reflect the different JAVA_HOME or in Eclipse selecting an "Alternate JRE". |
I originally thought the JVM environment variable of com.ibm.mq.cfg.useIBMCipherMappings was making the use of different JREs idiot proof to the developer/tester but that is not the case. If you have a mismatch between the JRE and the JVM environment variable, it throws an exception.
Regards,
Roger Lacroix
Capitalware Inc. _________________ Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|