Oct 28 2021

SSL Versions Supported on my JVM

Published by at 9:02 am under Java

SSL or TLS supported on a JVM can change depending on many things. Here are the many factors it depends on, and how to display which SSL versions are available and enabled on your JVM.


Factors Affecting SSL Support

SSL support depends first on your JDK version. TLS 1.0 and 1.1 are disabled on more and more JDK distributions by default, while TLS 1.2 is pretty standard. TLS 1.3 is supported on JDK 11 and later and JDK8 builds newer than 8u261.

But you can bypass default settings and disable a TLS algorithm in the Java security property file, just called java.security. SSL / TLS versions can be disabled with the jdk.tls.disabledAlgorithms setting.
There’s actually no way to enable explicitly a TLS version in Java: it has to be supported by the JDK distribution and not be in the disabled algorithm list.

You can always force the use of a TLS version, and cipher, in the java command parameters. Check last section.


Check SSL / TLS Versions Programmatically

Supported and enabled TLS versions can be displayed with a very simple piece of Java code. The getProtocols() method from the SSLContext class will help to display supported SSL versions on your JVM.

import java.util.*;
import javax.net.ssl.SSLContext;

public class tls
{

  public static void main (String[] args) throws Exception
  {
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, null, null);
    String[] supportedProtocols = context.getDefaultSSLParameters().getProtocols();
    System.out.println(Arrays.toString(supportedProtocols));
  }

}


Execute the following commands to show the JVM version along enabled and supported SSL protocol versions

java -version
echo "Supported TLS:"
javac tls.java
java tls


Some TLS versions on some servers of mine:

Default OpenJDK
openjdk version "1.8.0_302"
OpenJDK Runtime Environment (build 1.8.0_302-b08)
OpenJDK 64-Bit Server VM (build 25.302-b08, mixed mode)
Supported TLS:
[TLSv1.2]

IBM OpenJ9
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-b08)
Eclipse OpenJ9 VM (build openj9-0.18.1, JRE 1.8.0 Linux amd64-64-Bit
Compressed References 20200122_511 (JIT enabled, AOT enabled)
OpenJ9   - 51a5857d2
OMR      - 7a1b0239a
JCL      - 8cf8a30581 based on jdk8u242-b08)
Supported TLS:
[TLSv1, TLSv1.1, TLSv1.2]


And TLS versions on a mac:

JVM TLS supported versions

You have now a list of TLS versions enabled on your JVM that you can fully trust.


Check SSL Versions and Ciphers with the Debug Mode

If you want to go further and see what is actually going on, use the Java debug feature. You will get details on disabled SSL protocols, available ciphers, SSL handshake and so on. It is very verbose, you have been warned! But so useful.
Simply launch your java code with java -Djavax.net.debug=all. A simple program that connects to a Mariadb database with JDBC and SSL enabled would be launched with something like:

java -Djavax.net.debug=all \
     -Djavax.net.ssl.trustStore=keystore.jks \
     -Djavax.net.ssl.trustStorePassword=changeit \
     -cp "mariadb-java-client-2.7.3.jar:." myProgram


This will shows a lot of stuff about SSL protocol and ciphers. Some of the lines below:

System property jdk.tls.server.cipherSuites is set to 'null'
Ignoring disabled cipher suite: TLS_DH_anon_WITH_AES_256_CBC_SHA
[...]
update handshake state: client_hello[1]
upcoming handshake states: server_hello[2]
*** ClientHello, TLSv1.2
Cipher Suites: [TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
[...]
%% Initialized:  [Session-1, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256]
[...]
0000: 01 00 00 01 0A 49 00 00   02 03 64 65 66 12 69 6E  .....I....def.in
0010: 66 6F 72 6D 61 74 69 6F   6E 5F 73 63 68 65 6D 61  formation_schema
0020: 06 54 41 42 4C 45 53 06   54 41 42 4C 45 53 09 54  .TABLES.TABLES.T
0030: 41 42 4C 45 5F 43 41 54   0C 54 41 42 4C 45 5F 53  ABLE_CAT.TABLE_S
0040: 43 48 45 4D 41 0C 2D 00   00 01 00 00 FD 01 00 00  CHEMA.-.........
0050: 00 00 21 00 00 03 03 64   65 66 00 00 00 0B 54 41  ..!....def....TA
0060: 42 4C 45 5F 53 43 48 45   4D 00 0C 3F 00 00 00 00  BLE_SCHEM..?....
[...]

jdk.tls.server.cipherSuites is set to ‘null’ because it was not overridden.
There’s usually a long list of disabled ciphers since they’re linked to disabled TLS protocols for most of them.
Then you see the client hello that shows the TLS version used for the handshake.
Cipher Suites normally displays a long list of available ciphers on the JVM. There’s just one here because I forced it.
Going further down, we can even see SQL queries sent to the Mariadb server during the connection initialisation.
Oracle provides a good documentation on how to debug SSL/TLS going through these messages.


Forcing TLS Versions and Ciphers

It is possible to force the JVM to use some TLS versions and ciphers on the command line. That’s very handy if you don’t have access to the JVM configuration, or if you’d like special settings for a particular Java program.
This can be done with jdk.tls.client.protocols and jdk.tls.client.cipherSuites settings.

java -Djavax.net.debug=all \
     -Djavax.net.ssl.trustStore=keystore.jks \
     -Djavax.net.ssl.trustStorePassword=changeit \
     -Djdk.tls.client.protocols=TLSv1.2 \
     -Djdk.tls.server.cipherSuites="TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" \
     -cp "mariadb-java-client-2.7.3.jar:." myProgram


TLS protocols and ciphers can also be specified on the JDBC connection string if you use encryption for the database connection.

String url = "jdbc:mariadb://my_database_server:3306/my_database?"+
             "useSSL=true"+
             "&serverTimezone=UTC"+
             "&enabledSslProtocolSuites=TLSv1.2"+
             "&enabledSSLCipherSuites=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";

No responses yet

Trackback URI | Comments RSS

Leave a Reply