I use IBM JDK J9 on AIX OS.
I want to know what I need to change in the java.security file to enable the SSLv3 Secure Socket Layer protocol. Or is there another file that needs to be changed to enable this protocol?
Delete or comment out the following line "jdk.tls.disabledAlgorithms=SSLv3"
Related
We initialise our SSL context with the following code and are running on Java 8.
SSLContext context = SSLContext.getInstance("SSL");
Since Java 8 uses TLSv1.2 by default? Does it mean the above code will start sending TLSv1.2 requests if my server supports it.
Want to understand if "SSL" protocol name is just an alias but java runtime starts sending the requests with default TLS version.
UPDATE
I ran my code against "https://www.google.co.in/" and found this in fiddler
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.
Version: 3.3 (TLS/1.2
And also if i change my protocol to TLSv1 which only supports 1.0. Then Fiddler tells me
A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below.
Version: 3.1 (TLS/1.0)
So, I guess the above code with "SSL" protocol name should work well with TLS 1.2 servers.
Yes. In Java 7, server side default TLS version was 1.2. In Java 8 both server and client have default TLS version 1.2.
As TLS version is backward compatible on both side unless server is configured strictly to specific version should not be an issue.
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 after ibmwebspheremq<queue_manager_name> and shared the extracted certificates with the client application using ikeyman 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).
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.2.0</version>
</dependency>
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 this System.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 a self-signed certificate labeled after ibmwebspheremq<queue_manager_name> name and instead of extracting the .arm file, I export the certificate as .jks files. Both keystore.jks and truststore.jks files exported from the same certificate. After, attached them to the application using system properties;
System.setProperty("javax.net.ssl.trustStore", "truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "<password>");
System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "<password>");
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,
MQEnvironment.properties.put(com.ibm.mq.constants.CMQC.USER_ID_PROPERTY, "<user_name>");
MQEnvironment.properties.put(com.ibm.mq.constants.CMQC.PASSWORD_PROPERTY, "<password>");
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),
ALTER QMGR CONNAUTH(USE.PW)
DEFINE AUTHINFO(USE.PW) +
AUTHTYPE(IDPWOS) +
FAILDLAY(10) +
CHCKLOCL(OPTIONAL) +
CHCKCLNT(OPTIONAL)
REFRESH SECURITY TYPE(CONNAUTH)
Note that CHCKCLNT value needed to set as OPTIONAL 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.
Note: Adding answer to capture information provided to OP in comments that have been removed.
See the following IBM MQ Knowledge center page for a table showing cert type compatibility with MQ v9.1:
IBM MQ 9.1.x/IBM MQ/Securing/Confidentiality of messages/Enabling CipherSpecs
The ciphers with ECDHE_ECDSA require a suite b cert for the queue manager. If using a client cert for your application it will also need to be suite b.
Note that you can use ECDHE_RSA ciphers with non-suite b certs.
The stash file (key.sth for example) is used by the queue manager to access the kdb file. The java equivalent on the client end is you specifying the jks password.
Acording title i want to know how to check TLSv1.2 is enabled or not in server.
Server :
CentOS 7 ||
wildfly 10.1 ||
jdk 1.8.0_161
Thank you.
I am not aware if there is a wildfly specific way, but you can always use Wireshark, for monitoring traffic to the server.
Install it, apply a filter, where destination address is the server's address.
You will see something similar to this:
In my case, server supports TLSv1.2.
Alternatively you can specify -Djavax.net.debug=all which will log TLS handshake, from which it can be also clear TLSv1.2 is used.
Also note you can ensure TLSv1.2 is used by configuring WildFly with https://wildscribe.github.io/WildFly/10.1/subsystem/undertow/server/https-listener/index.html#attr-enabled-protocols
We have a java application which runs on Java Version: 1.7.0_80 and we are trying to enable TLSv1.2 with the jvm argument -Dhttps.protocols=TLSv1.1,TLSv1.2
-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2-Ddeployment.security.TLSv1=false
-Ddeployment.security.TLSv1.1=true
-Ddeployment.security.TLSv1.2=true to consume a web service which supports only TLSv1.2. Though we have the jvm argument java client still using TLSv1 for communicating with web services,
can someone please help me is there any jvm configurations I need to make to use TLSv1.2 without any code change?
Without any code change, as I wrote in the comment, you need at least 7u95.
jdk.tls.client.protocols system property. To enable specific SunJSSE
protocols on the client, specify them in a comma-separated list within
quotation marks; all other supported protocols are then disabled on
the client. For example, if the value of this property is
"TLSv1,TLSv1.1", then the default protocol settings on the client for
TLSv1 and TLSv1.1 are enabled on the client, while SSLv3, TLSv1.2, and
SSLv2Hello are disabled on the client. This propery has been available
since Java SE 7u95.
The same property is also available since Java 6u121, with Java 6 supporting and implementing TLS 1.2.
Because of the Poodle attack it is now recommended to disable SSLv3 for client and server applications and only allow TLS 1.0 -TLS 1.2 connections.
Is there a way to disable SSLv3 for all Java based applications (server and client) on a computer without having to modify every Java program?
May be there is a possibility to change the configuration of the JRE or using a special environment variable.
Does anybody know such a way?
You have not specified the version of Java because below Java 8 there is no way to disallow or disable specific SSL protocol but in Java 8 you can set the enabled protocols like following
Statically:
% java -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" MyApp
Dynamically:
java.lang.System.setProperty("jdk.tls.client.protocols", "TLSv1,TLSv1.1,TLSv1.2");
If you are still using java 7 or below try to use work around explained Instructions to disable SSL v3.0 in Oracle JDK and JRE
I just implemented following piece of code to disallow SSLv3 and SSLv2Hello on one of our Java6 application.
if(disabledSSLProtocols != null) {
String[] protocols = sslEngine.getEnabledProtocols();
List<String> protocolList = new ArrayList<String>();
for (String s : protocols) {
if (disabledSSLProtocols.contains(s)) {
log4j.info("{} protocol is disabled", s);
continue;
}
log4j.info("{} protocol is enabled", s);
protocolList.add(s);
}
sslEngine.setEnabledProtocols(protocolList.toArray(new String[0]));
}
Where disabledSSLProtocols initialized with SSLv3,SSLv2Hello
Take a look at http://www.oracle.com/technetwork/java/javase/overview/tlsreadme-141115.html
Relevant part:
Renegotiations can be re-enabled for those applications that need it by setting the new system property sun.security.ssl.allowUnsafeRenegotiation to true before the JSSE library is initialized. There are several ways to set this property:
Command Line:
% java -Dsun.security.ssl.allowUnsafeRenegotiation=true Main
Java Control Panel (Java Plug-in / Java Web Start) - Runtime Environment.
Within the application:
java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", true);
Note that TLS/SSL renegotiation will not occur unless both client and server have enabled renegotiations.
It explains the issue and the fix.
For https-connections using the java.net-package you could try using the environment-variable _JAVA_OPTIONS to set the system-property https.protocols:
_JAVA_OPTIONS=-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
should enable only the mentioned protocols. Note that before Java 7 the maximum supported version was TLSv1.
This solution will not affect any other SSL-connections or http-connections using e.g. the apache-http-connector.
You can patch Oracle Java now.
http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html