TLS 1.3 and the Coming NIST Mandate

TLS (Transport Layer Security) is a cryptographic protocol to secure network communication. TLS 1.3 is the latest version of the TLS protocol, succeeding TLS 1.2. TLS 1.3 aims to provide more robust security, higher privacy protection, as well as better performance than previous versions. Here is a brief introduction to TLS 1.3. Also, we discuss NIST's requirement for TLS 1.3 readiness and give examples of enabling TLS 1.3 in some commonly used web servers.

It takes 20 years to build a reputation and a few minutes of cyber-incident to ruin it.
Stéphane Nappo (Vice President and Global Chief Information Security Officer of Groupe SEB, France, 2018 Global CISO of the year)

Introduction to TLS 1.3

TLS 1.3 is the latest recommended cryptographic protocol for protecting a wide variety of network communications, including web browsing, email, online trading, instant messaging, mobile payments, and many other applications. By using TLS 1.3, more secure and reliable communication connections can be established, ensuring confidentiality, authenticity, and data integrity. It was standardized by the Internet Engineering Task Force (IETF) in August 2018, and published as RFC 8446.

TLS 1.3 introduces some important improvements over TLS 1.2. The table below presents a quick comparison of the two:

Aspect TLS 1.2 TLS 1.3
Protocol Design Request-response model Reduced round trips
Handshake Multiple round trips Single round trip
Cipher Suites Supports wide range, including insecure ones Focuses on stronger algorithms
Security Known vulnerabilities, e.g., CBC vulnerabilities Addresses previous issues, stronger security
Performance Higher latency due to more round trips Faster connection establishment
Resilience to Attacks Vulnerable to downgrade attacks and padding oracle attacks Additional protections against attacks
Compatibility Widely supported across platforms Increasing support, may not be available on older systems
Implementation Supports Available in many cryptographic libraries Supported in various libraries

It can be seen that enhanced security and performance improvements are the most notable features of TLS 1.3, and we can explore more into these in the following sections.

Security Hardening

Cipher Suites

The protocol design principle of TLS 1.3 has enhanced security as its primary goal. As a result, TLS 1.3 drastically reduces the number of supported cipher suites. It removes insecure and weak cipher suites, leaving only more secure and modern cipher suites. This helps to increase the security of communications and avoids the use of outdated or vulnerable cipher suites.

Specifically, TLS 1.3 removes various cipher suites that use static RSA key transport, static Diffie-Hellman key exchange, CBC mode of operation, or SHA-1. It adopts only a limited number of Authenticated Encryption with Associated Data (AEAD) cipher suites. AEAD can guarantee the confidentiality, integrity, and authenticity of data at the same time, and its high security makes it the exclusive choice for TLS 1.3.

On the other hand, the name string of the cipher suite used in previous TLS versions included all algorithms for key exchange, digital signatures, encryption, and message authentication. Each cipher suite is assigned a 2-byte code point in the TLS Cipher Suites registry managed by the Internet Assigned Numbers Authority (IANA). Every time a new cryptographic algorithm is introduced, a series of new combinations need to be added to the list. This has led to an explosion of code points representing every valid choice of these parameters. This situation also makes the selection of cipher suites complicated and confusing.

The design of TLS 1.3 changed the concept of the cipher suite. It separates the authentication and key exchange mechanisms from the record protection algorithm (including secret key length) and a hash to be used with both the key derivation function and handshake message authentication code (MAC). The new cipher suite naming convention is TLS_<AEAD>_<Hash>, where the hash algorithm is used for the newly defined key derivation function HKDF of TLS 1.3 and the MAC generation in the handshake phase. The cipher suites defined by the TLS 1.3 protocol are:

RFC 8446 - Appendix B.4. Cipher Suites
| Description | Value |
| TLS_AES_128_GCM_SHA256 | {0x13,0x01} |
| | |
| TLS_AES_256_GCM_SHA384 | {0x13,0x02} |
| | |
| TLS_CHACHA20_POLY1305_SHA256 | {0x13,0x03} |
| | |
| TLS_AES_128_CCM_SHA256 | {0x13,0x04} |
| | |
| TLS_AES_128_CCM_8_SHA256 | {0x13,0x05} |

This simplified cipher suite definition and greatly reduced set of negotiation parameters also speed up TLS 1.3 handshake, improving overall performance.

Key Exchange

TLS 1.3 emphasizes forward secrecy, ensuring that the confidentiality of communications is protected even if long-term secrets used in the session key exchange are compromised. It only allows key exchange based on ephemeral Diffie-Hellman key exchange (DHE) or ephemeral elliptic curve Diffie-Hellman key exchange (ECDHE). Both have the property of forward secrecy. Also, the protocol explicitly restricts the use of secure elliptic curve groups and finite field groups for key exchange:

/* Elliptic Curve Groups (ECDHE) */
secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
x25519(0x001D), x448(0x001E),

/* Finite Field Groups (DHE) */
ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
ffdhe6144(0x0103), ffdhe8192(0x0104),

The above elliptic curve groups for ECDHE are specified by RFC 8422. The first three are defined by the FIPS.186-4 specification and the corresponding NIST names are P-256/P-384/P-512, while the next two (x25519/x448) are recommended by ANSI.X9-62.2005. RFC 7919 specifies four finite field groups (ffdhe####) for DHE. The primes in these finite field groups are all safe primes.

In number theory, a prime number \(p\) is a safe prime if \((p-1)/2\) is also prime.

Signature Verification

For signature verification in the key exchange phase, TLS 1.3 introduces more signature algorithms to meet different security requirements:

  • RSA signature algorithm: TLS 1.3 still supports RSA-based signature algorithms, including RSA-PKCS1-SHA256, RSA-PKCS1-SHA384, etc. These algorithms use RSA keys for digital signatures.
  • ECDSA signature algorithm: TLS 1.3 introduces more signature algorithms based on elliptic curve cryptography (ECC), such as ECDSA-SHA256, ECDSA-SHA384, etc. These algorithms use elliptic curve keys for digital signatures and are generally superior to RSA in terms of security and performance.
  • EdDSA signature algorithm: TLS 1.3 also introduces the EdDSA (Edwards-curve Digital Signature Algorithm) signature algorithm based on the Edwards curve. It features efficient performance and strong security for mobile devices and resource-constrained environments.
  • RSASSA-PSS signature algorithm: In addition to the traditional RSA-PKCS1 signature algorithm, TLS 1.3 also introduces the RSASSA-PSS signature algorithm, which is a more secure signature method based on RSA and has better attack resistance.
  • PSK signature algorithm: TLS 1.3 supports the signature algorithm based on the pre-shared key (PSK), which applies to the PSK handshake mode. This approach does not involve a digital certificate but uses a pre-shared key for verification.

TLS 1.3 stops using the DSA (Digital Signature Algorithm) signature algorithm. This is also a notable difference from TLS 1.2. DSA has some security and performance limitations and is rarely used in practice, so TLS 1.3 removed support for DSA certificates.

Other Reinforcements

Additionally, TLS 1.3 includes the following improvements to enhance security

  • TLS 1.3 does not allow data compression. The data compression feature in earlier versions of TLS could lead to security issues such as CRIME attacks. To avoid this risk, TLS 1.3 removed support for data compression entirely.
  • Unlike earlier versions of TLS, TLS 1.3 prohibits renegotiation after the connection has been established. This helps reduce security risk and complexity. Renegotiation may introduce new security holes, and frequent negotiations during the connection process may also cause performance problems.
  • All handshake messages following the ServerHello message during the TLS 1.3 handshake are now encrypted. The newly introduced EncryptedExtensions message enables encryption protection of various extensions previously sent in plain text.
  • TLS 1.3 adds asymmetric cryptographic protection of the Certificate messages sent from the server to the client. This encryption prevents threats such as man-in-the-middle attacks, information leakage, and certificate forgery, further fortifying the security and privacy of the connection.

Performance Boosting

Simplified Handshake

The general trend towards high-speed mobile Internet requires the use of HTTPS/TLS to protect the privacy of all traffic as much as possible. The downside of this is that new connections can become a bit slower. For the client and web server to agree on a shared key, both parties need to exchange security attributes and related parameters through the TLS "handshake process". In TLS 1.2 and all protocols before it, the initial handshake process required at least two round-trip message transfers. Compared to pure HTTP, the extra latency introduced by the TLS handshake process of HTTPS can be very detrimental to performance-conscious applications.

TLS 1.3 greatly simplifies the handshake process, requiring only one round trip in most cases, resulting in faster connection establishment and lower latency. Every TLS 1.3 connection will use (EC)DHE-based key exchange, and the parameters supported by the server may be easy to guess (such as ECDHE + x25519 or P-256). Since the options are limited, the client can directly send the (EC)DHE key share information in the first message without waiting for the server to confirm which key exchange it is willing to support. This way, the server can derive the shared secret one round in advance and send encrypted data.

The following diagram compares the message sequences of the handshake process of TLS 1.2 and TLS 1.3. Both operate with public key-based authentication. The TLS 1.3 handshake shown below uses the symbols borrowed from the RFC 8446 specification: '+' indicates a noteworthy extension; '*' indicates an optional message or extension; '[]', '()', and '{}' represent encrypted messages, where the keys used for encryption are different.

TLS 1.2 handshake (left) vs. TLS 1.3 handshake (right)

This figure illustrates the following points:

  • TLS 1.3 removes several messages used by TLS 1.2: ServerHelloDone, ChangeCipherSpec, ServerKeyExchange, and ClientKeyExchange. The contents of TLS 1.2's ServerKeyExchange and ClientKeyExchange messages vary depending on the authentication and key-sharing method being negotiated. In TLS 1.3, this information was moved to the extensions of ClientHello and ServerHello messages. TLS 1.3 completely deprecates ServerHelloDone and ChangeCipherSpec messages, there is no replacement.
  • For TLS 1.3 the public key-based authentication mode is probably the most important. It always uses (EC)DHE to achieve forward secrecy. The figure shows that the ClientHello message carries four extensions that are must-haves in this mode: key_share, signature_algorithms, supported_groups, and support_versions.
  • During the TLS 1.2 handshake, the exchange of control data requires multiple round trips between the client and server. TLS 1.2's ClientKeyExchange and ChangeCipherSpec messages are carried in separate packets, and the Finished message is the first (and only) encrypted handshake message. The whole process needs to transmit 5-7 data packets.
  • During the TLS 1.3 handshake, encrypted Application Data is already sent by the client after the first round trip. As mentioned earlier, the EncryptedExtension message provides privacy protection for ServerHello extensions in earlier versions of TLS. If mutual authentication is required (which is common in IoT deployments), the server will send a CertificateRequest message.
  • The Certificate, CertificateVerify, and Finished messages in TLS 1.3 retain the semantics of earlier TLS versions, but they are all asymmetrically encrypted now. Echoing the description in the last section, by encrypting Certificate and CertificateVerify messages, TLS 1.3 better protects against man-in-the-middle and certificate forgery attacks while enhancing the privacy of connections. This is also an important security feature in the design of TLS 1.3.

In rare cases, when the server does not support a certain key-sharing method sent by the client, the server can send a new HelloRetryRequest message letting the client know which groups it supports. As the group list has shrunk significantly, this is not expected to happen very often.

0-RTT Session Resumption

0-RTT (Zero Round Trip Time) in TLS 1.3 is a special handshake mode. It allows clients to send encrypted data during the handshake phase, reducing the number of round trips required for connection establishment and enabling faster session resumption. The following is a brief explanation of the 0-RTT working mode:

  1. Store session tickets: During the normal TLS 1.3 handshake, the client and server generate a data structure called a "session ticket" during the handshake. Session tickets contain information about the connection, including key parameters and cipher suites. The server stores the session ticket provided by the client.
  2. 0-RTT handshake: When the client reconnects to the server, it includes the previously saved session ticket in the early_data extension of the ClientHello message, along with encrypted Application Data. The client encrypts 0-RTT data using a pre-shared key (PSK) obtained from a previous connection.
  3. Server Response: After the server receives this message, if it supports 0-RTT mode and can recognize and verify the session ticket, it sends an EncryptedExtensions message, and then confirms the connection in the Finished message. This way, the server can quickly establish a secure connection with 0 round trips. It can also immediately send data to the client to achieve 0-RTT data transmission.

The message sequence of the 0-RTT session resumption and data transmission process of TLS 1.3 is as follows:

TLS 1.3 0-RTT


  • Does the TLS 1.3 protocol allow the use of RSA digital certificates?

    A common misconception is that "TLS 1.3 is not compatible with RSA digital certificates". The description in the "Signature Verification" section above shows that this is wrong. TLS 1.3 still supports the use of RSA for key exchange and authentication. However, considering the limitations of RSA, it is recommended that when building and deploying new TLS 1.3 applications, ECDHE key exchange algorithms and ECC digital certificates are preferred to achieve higher security and performance.

  • During the TLS 1.3 handshake, how does the server request the client to provide a certificate?

    In some scenarios, the server also needs to verify the identity of the client to ensure that only legitimate clients can access server resources. This is the case with mTLS (mutual TLS). During the TLS 1.3 handshake, the server can specify that the client is required to provide a certificate by sending a special CertificateRequest extension. When the server decides to ask the client for a certificate, it sends a CertificateRequest extension message after the ServerHello message. This extended message contains some necessary parameters, such as a list of supported certificate types, a list of acceptable certificate authorities, and so on. When the client receives it, it knows that the server asked it for a certificate, and it can optionally respond to the request. If the client is also configured to support mTLS and decides to provide a certificate, it provides its certificate chain by sending a Certificate message.

  • Is 0-RTT vulnerable to replay attacks?

    TLS 1.3's 0-RTT session resumption mode is non-interactive and does risk replay attacks in some cases. An attacker may repeat previously sent data to simulate a legitimate request. To avoid and reduce the risk of replay attacks to the greatest extent, TLS 1.3 provides some protection measures and suggestions:

    1. The simplest anti-replay method is that the server only allows each session ticket to be used once. For example, the server may maintain a database of all valid tickets that have not been used, deleting each ticket from the database as it is used. If an unknown ticket is received, the server falls back to a full handshake.
    2. The server may limit the time window in which session tickets are accepted, that is, the time range in which 0-RTT data is allowed to be valid. This reduces the chance of an attacker successfully replaying.
    3. Clients and servers should also use 0-RTT data only for stateless requests, that is, requests that do not affect the state of the server such as HTTP GET. For requests that need to modify the state of the server or have an impact, restrict the use of normal handshake patterns only.
    4. Another way to prevent replay is to store the unique value (usually a random value or a PSK bundled value) derived from the ClientHello message, and reject duplicates. Logging all ClientHellos would cause the state to grow without bound, but combined with #2 above, the server can log ClientHellos within a given time window and use obfuscated_ticket_age to ensure that tickets are not duplicated outside the window use.
  • If the client does not know whether the server supports TLS 1.3, how could it negotiate the TLS version via handshake?

    The TLS protocol provides a built-in mechanism for negotiating the running version between endpoints. TLS 1.3 continues this tradition. RFC 8446 Appendix D.1 "Negotiating with an Older Server" gives specific instructions:

    A TLS 1.3 client who wishes to negotiate with servers that do not support TLS 1.3 will send a normal TLS 1.3 ClientHello containing 0x0303 (TLS 1.2) in ClientHello.legacy_version but with the correct version(s) in the "supported_versions" extension. If the server does not support TLS 1.3, it will respond with a ServerHello containing an older version number. If the client agrees to use this version, the negotiation will proceed as appropriate for the negotiated protocol.

    The following screenshot of a TLS 1.3 ClientHello message decode demonstrates this. The version number of the handshake message displayed on the left is "Version: TLS 1.2 (0x0303)". At the same time, it can be seen that the cipher suite section first lists 3 TLS 1.3 AEAD cipher suites, followed by 14 TLS 1.2 regular cipher suites. On the right, there are 4 extensions - key_share, signature_algorithms, supported_groups, and support_versions. The support_versions extension includes both TLS 1.3 and TLS 1.2 version numbers. This is the TLS version list for the server to choose from. Additionally, the key_share extension includes the client's preferred key-sharing method as x25519 and secp256r1(i.e. NIST P-256)

  • Does the TLS 1.3 protocol work with UDP and EAP?

    TLS was originally designed for TCP connections, and a variant DTLS (Datagram Transport Layer Security) for UDP was introduced later. Based on TLS 1.3, IETF has released the corresponding upgraded version of the DTLS 1.3 protocol RFC 9147. The design goal of DTLS 1.3 is to provide "equivalent security guarantees with the exception of order protection / non-replayability". This protocol was released in April 2022, and currently, there are not many software libraries supporting it.

    TLS can also be used as an authentication and encryption protocol in various EAP types, such as EAP-TLS, EAP-FAST, and PEAP. Corresponding to TLS 1.3, IETF also published two technical standard documents:

    • RFC 9190: EAP-TLS 1.3: Using the Extensible Authentication Protocol with TLS 1.3 (Feb. 2022)
    • RFC 9427: TLS-Based Extensible Authentication Protocol (EAP) Types for Use with TLS 1.3 (Jun. 2023)

    Both protocols are also quite new, and the software library updates supporting them are still some time away.

NIST Mandate

TLS 1.3 brings new security features and a faster TLS handshake. Since its release in 2018, many Internet services have migrated to this latest version. Nevertheless, widespread adoption across websites takes time. The non-commercial SSL Labs Projects has a dashboard called SSL Pulse that reports TLS/SSL security scan statistics for the most popular Internet sites. Below is the most recent chart of protocol support statistics by July 2023.

Source: SSL Pulse - 07/03/2023

As can be seen, of all 135,000+ probed sites the percentage of TLS 1.3 support is about 63.5%. That means there are still close to 50 thousand sites that do not leverage the security and performance benefits of TLS 1.3. Why? The decision to migrate a website to a new protocol version like TLS 1.3 can be complex and influenced by various factors. The top 3 common reasons hindering TLS 1.3 migration are

  • Compatibility Concerns: Some websites might have users who are still using outdated browsers or operating systems that do not support TLS 1.3. These websites need to maintain backward compatibility to ensure that all users can access their content securely.
  • Resource Constraints: Migration involves technical updates, configuration changes, and testing. Smaller websites or those with limited resources might face challenges in allocating the necessary time and effort to make these changes.
  • Third-Party Dependencies: Many websites rely on third-party services, content delivery networks, or other components. If these services do not yet support TLS 1.3, the website might delay migration to avoid disruptions or compatibility issues with these dependencies.

However, for network hardware/software vendors who want their products on the procurement list of any US public sector organization, there is a coming NIST mandate to make TLS 1.3 available by January 2024. This is stipulated in the National Institute of Standards and Technology Special Publication (NIST SP) 800-52 Rev. 2: Guidelines for the Selection, Configuration, and Use of Transport Layer Security (TLS) Implementations. Quoted from NIST SP 800-52 Rev. 2

3.1 Protocol Version Support

Servers that support government-only applications shall be configured to use TLS 1.2 and should be configured to use TLS 1.3 as well. ...

Servers that support citizen or business-facing applications (i.e., the client may not be part of a government IT system)10 shall be configured to negotiate TLS 1.2 and should be configured to negotiate TLS 1.3. ...

Agencies shall support TLS 1.3 by January 1, 2024. After this date, servers shall support TLS 1.3 for both government-only and citizen or business-facing applications. In general, servers that support TLS 1.3 should be configured to use TLS 1.2 as well. However, TLS 1.2 may be disabled on servers that support TLS 1.3 if it has been determined that TLS 1.2 is not needed for interoperability.

As in the RFC documents, "shall" above is a strong keyword that means that the definition is an absolute requirement of the specification. So this NIST publication requires all servers owned by the US government agencies to be able to support TLS 1.3 by 01/01/2024. They must run a minimum TLS version 1.2 by default and can be configured to do TLS 1.3 only if desired.

It is worth pointing out that this is not an official FIPS requirement, so not mandatory for the FIPS 140-3 certification at present. Besides, this NIPS document has a clear scope statement: "The scope is further limited to TLS when used in conjunction with TCP/IP. For example, Datagram TLS (DTLS), which operates over datagram protocols, is outside the scope of these guidelines. NIST may issue separate guidelines for DTLS at a later date." Based on this, we can infer that DTLS and EAP are out of consideration for this mandate.

Enabling TLS 1.3

The enhanced security and optimized performance of TLS 1.3 make it the first choice for securing communication of various network applications. Now we demonstrate how to enable TLS 1.3 function in three commonly used web server software Apache, Nginx, and Lighttpd.

NOTE: The implementation of many secure network communication applications relies on third-party SSL/TLS software libraries, such as wolfSSL, GnuTLS, NSS, and OpenSSL. Therefore, to enable the TLS 1.3 function of these applications, you need to ensure that the libraries they link with support TLS 1.3. For example, in September 2018, the popular OpenSSL project released version 1.1.1 of the library, with support for TLS 1.3 as its "top new feature".

Apache HTTP Server

The Apache HTTP Server is an open-source web server software from the Apache Software Foundation. Apache HTTP server is widely used and is one of the most popular web server software due to its cross-platform and security. Apache supports a variety of features, many of which extend core functionality through compiled modules, such as authentication schemes, proxy servers, URL rewriting, SSL/TLS support, and compiling interpreters such as Perl/Python into the server.

Apache HTTP Server has built-in support for TLS 1.3 since version 2.4.36, no need to install any additional modules or patches. The following command can be used to verify the version of the server

$ apache2ctl -v 
Server version: Apache/2.4.41 (Ubuntu)
Server built: 2020-04-13T17:19:17

Once the version is verified, the SSLProtocol line of the configuration file can be updated. The following will enable the Apache HTTP server to only support the TLS 1.3 protocol

# Only enable TLS 1.3
SSLProtocol -all +TLSv1.3

If the server needs to be compatible with clients that support TLS 1.2, you can add +TLSv1.2. After updating the configuration, restart the service

$ sudo service apache2 restart

Nginx Web Server

Nginx is a high-performance web server based on an asynchronous framework and modular design. It can also be used for reverse proxy, load balancer, and HTTP caching applications. It is free and open-source software released under the terms of a BSD-like license. Nginx uses an asynchronous event-driven approach to request processing, which can provide more predictable performance under high load. The current market share of Nginx is almost equal to that of the Apache HTTP server.

Nginx supports TLS 1.3 from version 1.13.0. The following command can be used to verify its version

$ nginx -v
nginx version: nginx/1.17.10 (Ubuntu)

In the Nginx configuration file, find the server block and modify the ssl_protocols line to enable TLS 1.3:

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/;

ssl_certificate /path/to/your/certificate.crt;
ssl_certificate_key /path/to/your/private-key.key;

# support TLS 1.2 and TLS 1.3
ssl_protocols TLSv1.2 TLSv1.3;


If you don't need to continue to support TLS 1.2, delete the TLSv1.2 there. After the modification is complete, you can run the following command to test the configuration of Nginx, and then restart the service

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

$ sudo service nginx restart

Lighttpd Web Server

Lighttpd is a lightweight open-source web server software. It focuses on high performance, low memory footprint, and fast responsiveness. Lighttpd is suitable for serving web applications and static content of all sizes. Its design goal is to provide an efficient, flexible, and scalable web server, especially suitable for high-load and resource-constrained (such as embedded systems) environments.

The first Lighttpd release to support TLS 1.3 is version 1.4.56. Starting with this version, the minimum version of TLS that Lighttpd supports by default is TLS 1.2. That is to say, Lighttpd supports TLS 1.2 and TLS 1.3 if no corresponding configuration file modification is made.

To limit the use of Lighttpd to only the TLS 1.3 feature, first make sure the mod_openssl module is loaded. Then in the configuration file lighttpd.conf, find the server.modules section, and add the following ssl.openssl.ssl-conf-cmd line:

server.modules += ("mod_openssl")
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/path/to/your/cert.pem"
ssl.privkey = "/path/to/your/privkey.pem"
ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.3",
"Options" => "-ServerPreference")

This will set the minimum version supported by Lighttpd to be TLS 1.3. Finally, save and reload the Lighttpd configuration for the changes to take effect:

sudo lighttpd -t -f /etc/lighttpd/lighttpd.conf # check configuration
sudo systemctl reload lighttpd