55
votes

I am trying to enable TLS 1.2 in my web app which uses JBoss 6.4 and Java 1.7. I have -Dhttp.protocols = TLSv1.2 in my application environment but it doesn't seem to work for me.

Is there anything I could do to enable TLS 1.2?

I wrote a simple program

context = SSLContext.getInstance("TLSv1.2");
context.init(null,null,null);
SSLContext.setDefault(context); 
SSLSocketFactory factory = (SSLSocketFactory)context.getSocketFactory();
SSLSocket socket = (SSLSocket)factory.createSocket();
protocols = socket.getEnabledProtocols();

After running this program within the app the TLS 1.2 gets enabled. I do not want to run this program but I want to directly enable it during app startup. Is there any way to do it?

10
sysprop https.protocols only works if spelled with both s's and only for connections made with URL.openConnection not some other means like SSLSocketFactory - dave_thompson_085

10 Answers

37
votes

There are many suggestions but I found two of them most common.

Re. JAVA_OPTS

I first tried export JAVA_OPTS="-Dhttps.protocols=SSLv3,TLSv1,TLSv1.1,TLSv1.2" on command line before startup of program but it didn't work for me.

Re. constructor

Then I added the following code in the startup class constructor and it worked for me.

try {
        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
        ctx.init(null, null, null);
        SSLContext.setDefault(ctx);
} catch (Exception e) {
        System.out.println(e.getMessage());
}

Frankly, I don't know in detail why ctx.init(null, null, null); but all (SSL/TLS) is working fine for me.

Re. System.setProperty

There is one more option: System.setProperty("https.protocols", "SSLv3,TLSv1,TLSv1.1,TLSv1.2");. It will also go in code but I've not tried it.

23
votes

You can upgrade your Java 7 version to 1.7.0_131-b31

For JRE 1.7.0_131-b31 in Oracle site :

TLSv1.2 and TLSv1.1 are now enabled by default on the TLS client end-points. This is similar behavior to what already happens in JDK 8 releases.

17
votes

Add following option for java application:

-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2  
10
votes

Add this parameter to JAVA_OPTS or to the command line in Maven: -Dhttps.protocols=TLSv1.2

8
votes

System.setProperty("https.protocols", "TLSv1.2"); worked in my case. Have you checked that within the application?

6
votes

The stated answers are correct, but I'm just sharing one additional gotcha that was applicable to my case: in addition to using setProtocol/withProtocol, you may have some nasty jars that won't go away even if have the right jars plus an old one:

Remove

<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

Retain

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.2</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.6</version>
</dependency>

Java is backward compatible, but most libraries are not. Each day that passes the more I wish shared libraries were outlawed with this lack of accountability.

Further info

java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
2
votes

To force enable TLSv1.2 in JRE7u_80 I had to use following code snippet before creating JDBC connection.

import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import javax.net.ssl.SSLContextSpi;
import sun.security.jca.GetInstance;
import sun.security.jca.ProviderList;
import sun.security.jca.Providers;

public static void enableTLSv12ForMssqlJdbc() throws NoSuchAlgorithmException
{
    ProviderList providerList = Providers.getProviderList();
    GetInstance.Instance instance = GetInstance.getInstance("SSLContext", SSLContextSpi.class, "TLS");
    for (Provider provider : providerList.providers())
    {
        if (provider == instance.provider)
        {
            provider.put("Alg.Alias.SSLContext.TLS", "TLSv1.2");
        }
    }
}

Able to connect to Windows 10 with SQL server 2017 & TLSv1.2 enabled OS.

0
votes

You should probably be looking to the configuration that controls the underlying platform TLS implementation via -Djdk.tls.client.protocols=TLSv1.2.

0
votes

I solved this issue by using

Service.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);
0
votes

I had similar issue when connecting to RDS Oracle even when client and server were both set to TLSv1.2 the certs was right and java was 1.8.0_141 So Finally I had to apply patch at Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files

After applying the patch the issue went away and connection went fine.