How to make Java application prefer TLS 1.3 over TLS 1.2?

An external system has a requirement that anyone accessing it should prefer TLS 1.3. How can I make my Java desktop application prefer TLS 1.3? I’m at Java 17, and TLS < 1.2 is disabled using jdk.tls.disabledAlgorithms.

From a search it seems that jdk.tls.client.protocols might be the desired system property, but is it somehow in “preferred order”? E.g., if I try the following:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL
jdk.tls.client.protocols=TLSv1.3,TLSv1.2

Will this now try 1.3 before trying 1.2? Is this verifiable somehow? Is it at all necessary, or will this somehow mimic some default behavior of Java 17 or above?

In Java 17, TLS 1.3 is supported by default, and it is preferred over TLS 1.2 when both protocols are available. However, to ensure your Java desktop application prefers TLS 1.3, you can use the jdk.tls.client.protocols system property to specify the preferred protocols in the desired order.

Setting Up TLS 1.3 Preference

To configure your Java application to prefer TLS 1.3, you can set the following system properties:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL
jdk.tls.client.protocols=TLSv1.3,TLSv1.2

Explanation

  • jdk.tls.disabledAlgorithms: This property disables certain older and insecure algorithms and protocols. By including TLSv1, TLSv1.1, and SSLv3, you ensure that these protocols are not used.
  • jdk.tls.client.protocols: This property allows you to specify which TLS protocols the client should prefer. By listing TLSv1.3,TLSv1.2, you instruct the JVM to prefer TLS 1.3, falling back to TLS 1.2 only if TLS 1.3 is not available.

Order of Preference

When you set jdk.tls.client.protocols as you described:

  • The Java runtime will attempt to negotiate the highest version first. So, in your case, it will try TLS 1.3 first, and only if that fails, it will then attempt TLS 1.2. This is the desired behavior, and you can confirm this through testing.

Verifying the Configuration

To verify that your application is indeed using TLS 1.3, you can enable debugging logs for the SSL/TLS handshake. You can do this by adding the following JVM option when running your application:

-Djavax.net.debug=ssl:handshake

This will produce detailed output of the SSL handshake process, including which protocols are being negotiated. Look for lines in the output that indicate the protocol used, such as:

*** ServerHello, TLSv1.3

Default Behavior in Java 17

Java 17 defaults to enabling TLS 1.3, so if no protocols are specified, it will automatically try to use TLS 1.3 when available. However, explicitly setting the jdk.tls.client.protocols property can be beneficial for clarity and to ensure your application’s behavior aligns with your requirements.

Finally

To ensure your Java desktop application prefers TLS 1.3, set the jdk.tls.disabledAlgorithms and jdk.tls.client.protocols properties as you have shown. This configuration will make sure that TLS 1.3 is preferred, and you can verify it using the SSL debugging output.