Configuring TLS 1.3 on WildFly application Server

This tutorial will teach you how to configure Transport Layer Security (TLS) v.1.3 on WildFly application server.

TLS 1.3 offers improved speed compared to TLS 1.2. The earlier version of TLS (1.2) required two round-trips to finish a TLS handshake. On the other hand, TLS 1.3 only needs to complete a single round-trip. This substantially reduces encryption latency and users will be able to browse websites faster and with greater security.

Besides that, TLS 1.3 has removed some deprecated features (SHA-1, RC4, DES and AES-CBC) that caused vulnerabilities to attacks such as the RC4 and BEAST exploits issues.

In order to configure TLS 1.3 on WildFly, we need an available ssl-context. You can check this tutorial to get started with WildFly and SSL: How to configure SSL/HTTPS on WildFly

Once you have an https listener available, you can check the SSL connection with cURL as follows:

curl -v -k https://localhost:8443
* Rebuilt URL to: https://localhost:8443/

* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384

As you can see, the SSL connection has been established using TLS 1.2. Now let’s switch to TLS 1.3.

In order to that, we will update our ssl-context configuration in the Elytron subsystem to specify the cipher-suite-names attribute. The format of this attribute is colon separated list of the TLS 1.3 cipher suites that you would like to enable.

You can check the list of available ciphers with the openssl command:

openssl ciphers -tls1_3 -v -s 
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD
TLS_AES_128_CCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESCCM(128) Mac=AEAD

Now let’s first switch the demoSSLContext to TLS 1.3:

[standalone@localhost:9990 /] /subsystem=elytron/server-ssl-context=demoSSLContext:write-attribute(name=protocols,value=[TLSv1.3])
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

Then, we will choose the list of cipher suites for our TLS 1.3 connection:

[standalone@localhost:9990 /] /subsystem=elytron/server-ssl-context=demoSSLContext:write-attribute(name=cipher-suite-names,value=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256)
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

That’s it. The following server-ssl-context will be available:

<server-ssl-contexts>
    <server-ssl-context name="demoSSLContext" cipher-suite-names="TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256" protocols="TLSv1.3" key-manager="demoKeyManager"/>
</server-ssl-contexts>

Reload the server configuration and check again the SSL connection with cURL as follows:

curl -v -k https://localhost:8443
* Rebuilt URL to: https://localhost:8443/

* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, [no content] (0):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, [no content] (0):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384

As you can see, the connection has been established using TLS 1.3 and the cipher suite TLS_AES_256_GCM_SHA384.

That’s it. You can apply the same configuration also to create the Client SSL Context, which can be used, for example by the mod_cluster subsystem when connecting to the load balancer using SSL/TLS:

    <client-ssl-context name="demoClientSSLContext" cipher-suite-names="TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256" protocols="TLSv1.3" key-manager="demoClientKeyManager"/>

TLS 1.3 vs TLS 1.3 Performance Test

Finally, I had a round of tests with JMeter to compare the throughput of a basic Web application using HTTPS and TLS 1.2/TLS 1.3 to see if the reduced number of round-trips actually works to improve the application performance.

The first test I have run, has been executed using the default WildFly 22 profile and default https configuration (TLS 1.2):

So, on average, requests were carried out in 35 ms with a Throughput of 269.1.

Next, I’ve configured WildFly to use TLS 1.3 with the set of ciphers discussed in this article. Here’s the JMeter report:

On average, using TLS 1.3, each request was carried out with 25ms with a Throughput of 365.7. Although this test is not rocket science, it still shows an improvement in application throughput around 35%. Which is not bad at all, isn’t it?