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
Related
Our company has upgraded from TLS 1.0 to TLS 1.2. Before this, we used to download files using org.apache.commons.net.ftp.FTPClient.
Now we cannot connect to the server using FTPSclent and we get an exception:
org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication
How can I correctly connect to the server.
Full stack trace:
First of all, turn on the SSL debug as the javadoc sugests and try to connect, then check the output (it logs by default to std out, you should redirect it to a file).
The sorter answer
Give a try to the -Dhttps.protocols=TLSv1.2 JVM argument (this should be passed to every java code that you are using during your investigation and you have to use the same JRE of course too).
If does not work, check the server certificate, that should be installed to the JRE's default keystore (cacerts) or your custom keystore that you may use.
If this does not help, install the JCE extensions (JRE could not handle a cert that has at least 2048 bit key without JCE).
If all of these steps are useless, you may have the same problem than this guy.
The longer version
I hope that you are using at least Java7 (see the table of the available protocols on each platform).
The first thing is, that the TLS protocols supported by the server and supported by your application have to have an intersect.
In this table you can find the default TLS protocols of the different JRE versions, this is important because your client uses very probably the default TLS of the JRE.
So after you have checked your JRE and found the supported TLS versions, you should check the applied cyphers.
You should test your connection using nmap:
nmap.exe --script ssl-enum-ciphers -p <port> <ftp host>
with this tool, you can list the TLS version and the used cyphers. The cypher list can be compared with the list provided by this small java code. This two lists have to have at least one common point in order to be able to communicate.
You can download the server's certificate using Portecle, that certificate should be installed in the keystore of your client JRE.
If you have found that they have intersection in TLS protocols and in cyphers too, you have the right cert in your keystore, you can test that they can communicate with
SSLPoke
If this works too, then the problem should be in FTPClient.
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.
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.
Is there any way to disable the use of TLS v1.1 (and v1) for all SSL configured listeners in Glassfish 4.1? I've tried to set the JVM property
-Ddeployment.security.TLSvX.Y=false
as recommended by this Oracle blog post (https://blogs.oracle.com/java-platform-group/entry/java_8_will_use_tls) but the protocols are still being used in the https negotiations.
Ok, i've found how to do it by messing around with Glassfish command interface.
Run the following commands:
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.ssl.tls-enabled=false
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.ssl.tls11-enabled=false
And this will leave only TLSv1.2 enabled. This commands are run against the default HTTPS listener (port 8181), so remember to run against any other secure HTTP listener if you need to.
The SSLSocket.getEnabledProtocols() method returns the following: [SSLv2Hello, SSLv3, TLSv1]. And indeed, when I call connect() and I have SSL debugging turned on, I see that a v2 client hello is used:
main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
But I have found two (admittedly old) references that say JSSE does not support SSL version 2:
From Fundamental Networking in Java:
'SSLv2Hello' is a pseudo-protocol which allows Java to initiate the handshake with an SSLv2 'hello message'. This does not cause use of the SSLv2 protocol, which is not supported by Java at all.
And from the JSSE Reference Guide:
The JSSE implementation in the J2SDK 1.4 and later implements SSL 3.0 and TLS 1.0. It does not implement SSL 2.0.
Now, my understanding is that version 2.0 client hello should only be sent when the client does support SSL version 2.0. From RFC 2246:
TLS 1.0 clients that support SSL Version 2.0 servers must send SSL
Version 2.0 client hello messages [SSL2] ... Warning: The ability to send Version 2.0 client hello messages will be phased out with all due haste.
So why does Java use it?
Sun's JSSE doesn't support SSLv2 but it supports the SSlv2ClientHello, to support some SSL servers that require it. You can turn it off by removing it from the enabled protocols.
IBM's JSSE does support SSLv2 entirely.
From the JSSE Reference Guide:
For example, some older server
implementations speak only SSLv3 and
do not understand TLS. Ideally, these
implementations should negotiate to
SSLv3, but some simply hangup. For
backwards compatibility, some server
implementations (such as SunJSSE) send
SSLv3/TLS ClientHellos encapsulated in
a SSLv2 ClientHello packet. Some
servers do not accept this format, in
these cases use setEnabledProtocols to
disable the sending of encapsulated
SSLv2 ClientHellos.
I imagine 'server implementations' should read 'SSL implementations' above.
EDIT: thanks for citing my book!
I faced the same issue, we had this error on our RCP application, it was trying to access our nginx which only handle TLS protocols. but openjdk which we use has a bug with TLS which in some case will end in: javax.net.ssl.SSLException: Received fatal alert: bad_record_mac. So i was trying to find a way to use a different protocol to do the handshake like SSLv3. At first I though that SSLv2Hello is the handshake protocols! but it is not!
SSLv2 never implemented in sun jdk or openjdk, this SSLv2Hello is not the actual protocol for the handshake, it is there for backward compatibility(my guess is because of the probability of existence of some servers) and it will be used for negotiation on the available protocols that will be used for the actual handshake!
on this link search for the answer from Stoinov, he wrap the answer very well.