I'm trying to configure an application running on Java 8 to support only TLSv1.2 connections. I've seen posts about altering .../jre/lib/security/java.security, using -Ddeployment.security.TLS* arguments when launching the JVM, and of course specifying an SSLContext of "TLSV1.2" in the code.
I've managed to get the server to support only TLSv1.1 and TLSv1.2, but have been unsuccessful at also turning away TLSv1.1 connections.
Any help would be appreciated. Thanks.
Editing security.java does work, assuming you have all the necessary commas.
Related
I need to Configure TLSv1.2 in WebSphere 7.0.0.45 (Java 1.6 SR 16 FP60). So I configured the Dynamic outbound configuration in WAS and Configured the SSL Configuration by following the steps in the links
https://developer.ibm.com/answers/questions/244958/how-do-i-configure-step-by-step-dynamic-outbound-e/
And I added the Custom property in Global Security and JVM Custom property
com.ibm.websphere.ssl.include.ECCiphers = true
After configuration I am able to Establish the connection with TLSv1.2 for
https://fancyssl.hboeck.de/ which only support TLSv1.2.
But I can't establish a connection for strong Cipher suite sites like
TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003C)
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009C)
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009D)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xC027)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xC028)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F)
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xC030)
It's throwing an
Fatal Error : Handshake Failure in ClientHello
I tried downloading the Unrestricted IBM Java policy files too. Still no luck
Please suggest me some best practice to configure TLSv1.2 in WAS7.0 and configure the Strong Cipher Suites to resolve the issue.
I opened a PRM with IBM for the same problem. After several iterations, I have not been able to solve it yet.
IBM suggested to me to install the unrestricted policy file. After doing it I could install the ssl certificate doing a "Retrieve from port" from the was admin console. But the problem continue while trying to connect from the appl.
You may tray the same to see if it works for you following the steps here:
https://developer.ibm.com/answers/questions/178395/how-do-i-install-the-unrestricted-policy-files-in.html
I have a legacy java web application that makes calls to an external webservice. The provider of that service is turning off TLS1.0 support. So, I am trying to see how the application can continue to work with the service.
The options I have seen are a) use BouncyCastle JCE instead of Java JCE http://boredwookie.net/index.php/blog/how-to-use-bouncy-castle-lightweight-api-s-tlsclient/, which I guess requires code change/ recompile (we don't have the luxury of doing it) or 2) use proxy servers https://www.reddit.com/r/sysadmin/comments/48gzbi/proxy_solution_to_bump_tls_10_connection_to_tls_12/
I have tried nginx proxy - it doesn't seem to handle the switch between TLS1.0 incoming and TLS1.2 that the end server expects.
server { listen 443 ssl; server_name proxy.mydomain.com;
ssl_certificate D:/apps/openssl/proxy.mydomain.com.cert;
ssl_certificate_key D:/apps/openssl/proxy.mydomain.com.private;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP;
ssl_prefer_server_ciphers on;
location / {
proxy_pass https://fancyssl.hboeck.de/;
}
This fails with a 502/ bad gateway error since https://fancyssl.hboeck.de only support TLS1.2 but works with https://www.google.com that supports TLS1.0.
I am doing this on Windows.
It's not TLSv1.2, it's lack of SNI leading to renegotiation.
First, I set up nginx (1.8.1/Windows) with a config like yours except using my own key&cert and proxying to my own test server. It worked fine, connecting from Java6 requester with TLSv1.0 and to server with TLSv1.2 (and even ECDHE-RSA-AES256GCM-SHA384, one of the 'best' ciphersuites) and returned pages just fine. I tried fancyssl.hboek.de and got 502 like you.
With wireshark I saw that nginx does not send SNI (by default) and at least using the IPv4 address 46.4.40.249 (I don't have IPv6) that server apparently hosts more than one domain because without SNI it provides a different (and expired!) certificate, for *.schokokeks.org, and after the first application data (the request) it sends an encrypted handshake (a renegotiation request -- which nginx does not honor). Testing with openssl s_client confirms that the server with SNI immediately sends the page but without it renegotiates first; repointing nginx to openssl s_server confirms that if the server requests renegotiation, receives no response, and closes nginx treats that as 502.
I would guess that Apache is renegotiating because it realizes the requested Host is not covered by the certificate -- except that it again uses the 'wrong' certificate. I haven't tried to track that part down.
Google does support TLSv1.2 (and ECDHE-RSA-AESGCM) when I connect, but even without SNI doesn't renegotiate, presumably because it's such high volume nothing else runs on www.google.com servers and there's no ambiguity. My test server doesn't have vhosts so didn't need SNI.
The nginx documentation reveals a directive proxy_ssl_server_name which can be set on to enable SNI, and then proxying to this server works.
FYI: several of the statements on that webpage are wrong, although its conclusion (if possible use TLSv1.2 with ECDHE or DHE and AES-GCM) is good.
Also, most of your ssl_ciphers string is useless, but you didn't ask about that.
ssl_ciphers HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP
HIGH is an excellent start.
SEED is useless in a server used (only) by Java/JSSE client, because it's not implemented on the Java side. Even outside of Java it was pretty much used only in South Korea, where it was created as an alternative to DES or IDEA, and even there it is mostly obsoleted by ARIA which is an alternative to AES -- but is not implemented by OpenSSL and hence nginx.
aNULL is probably unneeded because JSSE disables 'anonymous' suites by default, but here it's worth it as defense in depth.
!eNULL does nothing; no eNULL suites are in HIGH, or DEFAULT, or even ALL. You can only get them explicitly or with the bizarre COMPLEMENTOFALL -- which you shouldn't.
!EXPORT !DES !RC4 do nothing; none of them are in HIGH. If instead you started from DEFAULT on older versions of OpenSSL, or from ALL, then they would be good.
!PSK is unneeded; nginx doesn't appear to configure for PSK and JSSE doesn't implement it anyway.
!RSAPSK is ignored because OpenSSL doesn't implement that keyexchange, and if it did those suites are already covered as above.
!aDH !aECDH are covered by !aNULL and thus do nothing.
!EDH-DSS-DES-CBC3-SHA is silly; there's no reason to exclude this one suite when you keep other DHE_DSS and 3DES suites.
!KRB5-DES-CBC3-SHA is ignored because OpenSSL doesn't implement Kerberos, and if it did nginx wouldn't be configured for it plus again it would be silly to exclude one suite while keeping similars.
!SRP is unneeded; like PSK nginx apparently doesn't configure and JSSE doesn't implement.
So: HIGH:!aNULL is all you need.
In an attempt to harden my ssl server I have inadvertently broken a third party integration. They need Java 7u25 support in our SSL config and now we apparently do not have it with this config.
ssllabs.com says we have "Java 7u25 Protocol or cipher suite mismatch"
we have configured ssl.conf
# SSL Protocol support:
SSLProtocol -SSLv2 -SSLv3 -TLSv1 +TLSv1.1 +TLSv1.2
# SSL Cipher Suite:
SSLCipherSuite
ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-AES256-GCM-SHA384:
ECDHE-RSA-AES256-SHA384:
ECDHE-ECDSA-AES256-SHA384:
ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:
ECDHE-ECDSA-AES128-SHA256:
AES128-GCM-SHA256:
AES256-GCM-SHA384:
AES128-SHA256:
AES256-SHA256:
AES:
!aNULL:
!eNULL:
!EXPORT:
!DES:
!RC4:
!MD5:
!PSK:
!aECDH:
!EDH-DSS-DES-CBC3-SHA:
!EDH-RSA-DES-CBC3-SHA:
!KRB5-DES-CBC3-SHA
(formatting of cipher suites in ssl.conf is all in one line without spaces; it was changed one per line in this post for readability)
Thank you
By default Java 7 needs TLSv1 support which you've disabled. Re-enable it and you might be able to use that AES cipher depending what that corresponds to, but it probably can't use the SHA256 or SHA384 ones (again in default mode).
Best to run your site through ssllabs.com again and then compare the ciphers available to the Java 7 list: https://www.ssllabs.com/ssltest/viewClient.html?name=Java&version=7u25
Btw Java 7 can support TLSv1.1 and TLSv1.2 but not by default (see here: https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html) and have seen people struggle to get them working.
I have a VM running a Weblogic Server (running version 10.3.6) with 2 nodes. I also have a Tomcat server running on my host machine which runs an SSL web service, that the Weblogic Server has to connect to. I added the two startup parameters to the "Arguments" text area under startup:
-Dweblogic.security.SSL.protocolVersion=TLSv1.1
-Dweblogic.security.SSL.minimumProtocolVersion=TLSv1.1
I added these since the nodes were trying to connect using SSLv2 before, and causing a handshake error with Tomcat.
After adding these parameters, I still see the nodes trying to connect to Tomcat using SSLv2. I'm trying to get it to use TLS. What else can I do to get it to use TLS?
You're probably not using SSLv2, but an SSLv3 or TLS1.x ClientHello wrapped into an SSLv2 ClientHello. See "Why does Java's SSLSocket send a version 2 client hello?" or "How to initiate ssl connection using SSLv2".
Note that the latest JSSE Reference Guide (JDK 8) says:
Note: As part of disabling SSLv3, some servers have also disabled SSLv2Hello, which means communications with SSLv2Hello-active clients (e.g. JDK 1.5/6) will fail. Starting with JDK 7, SSLv2Hello default to disabled on clients, enabled on servers.
The Java 7 release notes also say:
SSLv2Hello disabled by default on the client: In Java SE 7, SSLv2Hello is removed from the default enabled protocol list on the client.
It's possible that you're using an older JRE or that for whatever reason, SSLv2Hello was explicitly enabled on your clients.
The protocolVersion value should be TLS1 instead of TLSv1.1.
https://docs.oracle.com/middleware/1213/wls/SECMG/ssl_version.htm#SECMG636
Setting -Dweblogic.security.SSL.minimumProtocolVersion=TLSv0 as java option, will set the minimum protocol to SSLV3 and will eliminate the use of SSLV2.
This worked for me.
TLSv0 is invalid, and WebLogic 12.1.3 will set SSLV3 as minimum.
What is the Java version that you're using with WebLogic?
TLS 1.1 is available at Java 1.6 Update 111. That might be why it is not working. That using TLSv1 as value
I have configured Jetty embedded server to include/exclude some protocols and cipher suites. Is there way to report those on working service? I think about something like getSupportedCipherSuites() and getSupportedProtocols() of javax.net.ssl.SSLServerSocket but for Jetty server objects. My code already shows things from configration:
HTTPSPDYServerConnector SSLconnector = new HTTPSPDYServerConnector(server, sslContextFactory);
SSLconnector.setPort(PortHTTPS);
...
server.setConnectors(new Connector[] { SSLconnector });
...
showInfo(sslContextFactory.getIncludeCipherSuites());
showInfo(sslContextFactory.getExcludeCipherSuites());
showInfo(sslContextFactory.getIncludeProtocols());
showInfo(sslContextFactory.getExcludeProtocols());
...
server.start();
Now I want to see what protocols and cipher suites are available for clients.
EDIT (more info):
My environment can work with those protocols:
SSLv2Hello
SSLv3
TLSv1
TLSv1.1
TLSv1.2
This is result of SSLServerSocket.getSupportedProtocols() that is reported by http://www.java2s.com/Code/JavaAPI/javax.net.ssl/SSLServerSocketgetSupportedProtocols.htm
But with Jetty environment I do not know how to get such list. I excluded some protocols by calling
sslContextFactory.addExcludeProtocols() (I disabled TLSv1.2 because of Chrome bug ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED in Google Chrome)
How can I get list of protocols available (not excluded) for Jetty server?
I suppose that for my environment such result will be:
SSLv2Hello
SSLv3
TLSv1
TLSv1.1
(TLSv1.2 was disabled)
I've just gone through a similar problem.
The way Jetty works, it instantiates a default SSLEngine and then it applies exclusions and other preferences. By default, Jetty 9.4 excludes the following protocols:
this.addExcludeProtocols("SSL", "SSLv2", "SSLv2Hello", "SSLv3");
Ciphers are managed in a similar way, but you can uge regexes. By default, Jetty 9.4 excludes the following:
this.setExcludeCipherSuites("^.*_(MD5|SHA|SHA1)$");
this.addExcludeCipherSuites("^TLS_RSA_.*$");
this.addExcludeCipherSuites("^SSL_.*$");
this.addExcludeCipherSuites("^.*_NULL_.*$");
this.addExcludeCipherSuites("^.*_anon_.*$");
If you call the include/exclude methods yourselp, you will have to deal with the particular sequence of processing that Jetty performs, which is potentially confusing. So I recommend you use the setter methods first with empty arrays, in order to clear anything Jetty put in place by default, and then add your preferred items. Example:
// empty the collections, we don't need no education
sslContextFactory.setExcludeProtocols(new String[]{});
sslContextFactory.setExcludeCipherSuites(new String[]{});
// tell me what you want, what you really really want
sslContextFactory.setIncludeProtocols("TLSv1","TLSv1.1","TLSv1.2");
sslContextFactory.setIncludeCipherSuites(omgIveNeverSeenSuchABigArrayOfCiphers);
If you need a list of ciphers that a specific Java client supports, run that client with -Djavax.net.debug=ssl:handshake:verbose and look for ClientHello messages.