top of page
  • Writer's pictureMichael Paltsev

In Depth TLS for Java Developers

Updated: Apr 23, 2023


In the previous post, we showed how to create a very simple REST client/server application with TLS enabled. We've talked a bit about Wireshark and also created a self-signed certificate and showed how to use it in our Java application. So what else is to it? Well... You are about to find out.


Java Secure Socket Extension

In the previous article, we implemented a client and a server that communicated over TLS. But we didn't write any code that has to do with TLS. So how and where is it implemented? The Java Secure Socket Extension (JSSE) is responsible for providing the framework and the implementation of the TLS (and also DTLS) protocols.


Why is it important to know that? Because JSSE provides us with some important features.


Along with the TLS implementation comes the cipher suites, interfaces that enable us to implement non-trivial logic, and implementations that help us with the configuration of JSSE.


Debugging

One of these implementations helps with what every beginning developer, after writing his first bugs, err lines of code, learns: debugging. Trying to find out what's wrong with what you wrote is often harder than writing it.


TLS, as we quickly find out, is not an exception.


If your solution does not work well, and you happen to own both of the communicating parties, debugging can be much easier. But even then, things may not work and you may not know why.

Thankfully, JSSE has you covered. Just add the system property javax.net.debug with one of the values:

  • empty - i.e., the property is there but has no value. In this case, you can use your logger (that implements the System.Logger) to output the logs

Or,

  • all - will output all debugging information

  • ssl - will output only SSL debugging information

And you will have the debug information printed out to the System.err (and in some cases to System.out ...).


If you want to see only SSL debugging information you can fine-grain the output with other settings such as defaultctx, handshake, record, and session (a complete list can be found here: https://docs.oracle.com/en/java/javase/17/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-31B7E142-B874-46E9-8DD0-4E18EC0EB2CF).

An example of that will be:

java -Djavax.net.debug=ssl,defaultctx,handshake,record,session -jar myApp.jar

Other Important Properties

Apart from debugging you can also set several other settings using JSSE. Those settings can be set as Java Security properties and also as System Properties.


There are two different ways of settings these settings: statically and dynamically.


You probably already know how to set System Properties statically and dynamically so we'll just jump over to Java Security. To set the properties statically you'll need to set them in the java.security file located in the JAVA_HOME folder under /conf/security.

To set it dynamically, you can use:

java.security.Security.setProperty("propertyName", "propertyValue");

The best way to handle it though, in my humble opinion, is to override/append to the java.security properties file. In this way, you are not modifying the security settings for all the JVM applications but only for yourself.


If the setting security.overridePropertiesFile in the java.security equals to true then you can just set the java.security.properties system property to point to the overriding/appending properties file. One important note here is that if you want to override the file, you'll need to use a double equals sign:

-Djava.security.properties==/some/path/to/override/java.security

Whereas, if you just want to append, you use only one equals sign:

-Djava.security.properties=/some/path/to/append/java.security

Below you can find a non-complete list of properties, for Java 17, with an explanation and their location (please note that these properties are currently used by the JSSE implementation and may be changed in later versions or not be supported by other implementations. You can find more here: https://docs.oracle.com/en/java/javase/17/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-A41282C3-19A3-400A-A40F-86F4DA22ABA9):

  • jdk.tls.client.protocols - (System Properties) a comma-separated list of supported TLS protocols by the Java client. The values are case-sensitive. E.g., TLSv1.2,TLSv1.3.

  • https.protocols - (System Property) same as above but only applicable for clients that use the HttpsURLConnection class.

  • jdk.tls.server.protocols - (System Property) same as for the client, but as the name suggest used by the server.

  • jdk.tls.maxCertificateChainLength - (Security Property) the maximum length of the certificate chain in a TLS handshake. The default value is 10.

  • jdk.tls.disabledAlgorithms - (Security Property) disables specific negotiation algorithms even if they are enabled in the application.

  • javax.net.ssl.keyStore - (System Property) the location of the key store

  • javax.net.ssl.keyStorePassword - (System Property) the password of the key store

  • javax.net.ssl.keyStoreType - (System Property) the type of the key store

  • javax.net.ssl.trustStore - (System Property) the location of the trust store

  • javax.net.ssl.trustStorePassword - (System Property) the password of the trust store

  • javax.net.ssl.trustStoreType - (System Property) the type of the trust store


Cipher Suites

If you read the article about TLS you probably know that cipher suites are very important to us as well. But how do we know what cipher suites are enabled? To get the list of the enabled cipher suites, you need to run the following command:

keytool -showinfo -tls

It will output the supported list of TLS protocols and the enabled cipher suites.


Troubleshooting

We've learned about debugging and setting some of the properties. Now it's time to troubleshoot some issues.

First things first, if you are having an issue with your TLS connection, set debugging up.

I can go on here about many of the configuration issues that may cause TLS to fail, but I think that Oracle wrote some good documentation about it and there is no need to rewrite it again: https://docs.oracle.com/en/java/javase/17/security/java-secure-socket-extension-jsse-reference-guide.html#GUID-E8E3C6C4-5B7E-466F-B11C-35BF3B9F454D


Conclusion

This was a relatively short, but hopefully informative, article that should give you guys some more knowledge and tools when working with TLS in Java. Please be wary about the security settings you set for your application - sometimes a bad security setting is all it takes to bring a company down.

84 views0 comments
bottom of page