I need to connect to a webservice which only accepts connections established via TLS 1.2. Other versions are not supported.
My test client (soapUI Pro) uses JRE 1.7_45 which - according to the following link - generally supports TLS 1.2 which is not enabled by default for clients. I don't have control over the test client's source code so I need to enable TLS 1.2 via some Java options or else.
http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#tlsprotonote
However I cannot find any information how to enable TLS 1.2 for the JVM.
The following parameter must be added to the soapUI vmoptions file in soapUI's bin directory:
-Dsoapui.https.protocols=TLSv1.2
You need to pass the protocol to SSLContext - docs
SSLContext context = SSLContext.getInstance("TLSv1.2");
You can then use context to create an SSLEngine
context.createSSLEngine();
Read the JSSE guide on how to make SSL connections using SSLEngine
Related
The service provider who is hosting a rest service is asking to communicate using TLS version 1.2 only.
So now I need to make my application to communicate with that service using TLS v 1.2.
I know, in java8 we have an option of disabling the legacy version of TLS and SSL using the property jdk.tls.disabledAlgorithms=SSLv3, RC4 in java.security file.
But in a server there will be other process using the same java settings, so I'm worried like if I change for that property in java.security file, then it will be applicable to other services which are using the same settings.
Question:
I would like to know if there is any other way to make my rest calls use only particular TLS version, through application code using java/spring libraries ?
Create a SSLContext to use the required protocol:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
If the client code or library uses HttpsURLConnection then you can set the default SSLSocketFactory for all the HTTS Connections:
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
Or at a per connection level:
HttpsURLConnection urlConnection = ....;
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.connect();
Different libraries may have different systems to provide the SSLSocketFactory or SSLContext.
For example, if you are using JAX-RS, you can create a REST client that uses the SSLContext with:
Client client = ClientBuilder.newBuilder().sslContext(sslContext).build();
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.
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.
On client side I have Apache HTTP client on jdk5u22. On server side I have tomcat on jdk6u27.
With this setup if I try SSL Client authentication (2 way SSL) then it cause "javax.net.ssl.SSLHandshakeException: Insecure renegotiation is not allowed" on the server and handshake fails. It succeeds if I set system properties sun.security.ssl.allowUnsafeRenegotiation=true and sun.security.ssl.allowLegacyHelloMessages=true on server.
As per the link http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html this is coz JRE6u27 has the RFC 5746 implementation and JRE5u26 below doesnt have this and so both are incompatible. Unfortunately 5u22 is the latest freely available java 5 version. So I want to know if it is possible to have SSL client authentication without ssl re-negotiation.
Regards,
Litty Preeth
As per the redhat site https://access.redhat.com/kb/docs/DOC-20491#Renegotiations_disabled_in_Apache_Tomcat :
Tomcat may ask the client to renegotiate in certain configurations using client certificate authentication, for example, configurations where:
A client certificate is not required on the initial connection, such as when:
1. The clientAuth attribute of the HTTPS connector using JSSE is set to
false. Or The SSLVerifyClient attribute of the HTTPS connector using
OpenSSL is set to none.
AND
2. A web application specifies the CLIENT-CERT authentication method in
the login-config section of the application's web.xml file.
So to avoid re-negotiation in tomcat just make the whole site secure and not just a part of it by setting clientAuth="true" for ssl .
Hope this helps someone.
Regards,
Litty
I would like to run a servlet in Jetty on an HTTPS site that requires a client certificate for only part of the site (specific URLs). For example:
https://example.com/someservlet/public - no client cert required
https://example.com/someservlet/protected - client cert required
In Apache I can accomplish this by specifying SSLVerifyClient require inside a <Directory> or <Location> which forces Apache to renegotiate the SSL connection after the request is made.
I do not want to run Jetty embedded in anything else, just standalone. Is this possible? Can a Servlet cause this directly somehow? Can it be done via configuration?
As far as I know you can only specify the SSL options on a per-port basis.
Even if you could the configuration you are trying to achieve is problematic, as it needs the SSLRenegotiation which has been changed about a year ago because of a security vulnerability. The new method for performing an SSLRenogitiation is therefore only supported by newer clients and sometimes even if it is supported it does not work because of bugs.
My recommendation for an easy workaround: Configure Jetty to listen on two SSL ports:
For example on 443 without HTTPS Client auth and on 8443 with HTTPS client auth required. Then make your protected servlet only available on 8443. This is not a nice solution but 100% robust, works with Jetty and with all clients.