Until the day TLS 1.3 becomes widely supported, web servers must rely on a fallback to TLS 1.2 with correctly configured server directives and strong cipher suites. Pick the wrong settings and you declare an open season on your server.
The basics of TLS
The Transport Layer Security protocol (TLS) can secure communications between parties and is widely used with a variety of application-level protocols.
The bad news is that all versions of TLS, except for TLS 1.3 as of this writing, have been compromised in one way or another and their fatal flaws are widely documented.
TLS serves three main objectives: authenticate peers, prevent eavesdropping, and tamper-proof their communications by validating the authenticity of messages. Different algorithms serve different purposes.
The TLS handshake
During the initial negotiation, the client and server have to agree on a set of parameters that define how the communication channel will be secured, and exchange session keys in order to establish a secure channel. This is the handshake phase.
The TLS handshake establishes one or more input secrets. The key derivation algorithmcombines these input secrets to create the actual working keying material. This process relies on both the input secrets and the transcript of the handshake itself.
During the handshake, the peers rely on asymmetric encryption. The sender uses the recipient’s public key to encrypt a message. The recipient uses its own private key to decrypt it upon receipt. During the handshake, the peers perform a key exchange to open a secure channel.
Key derivation and authentication
The key derivation process in TLS 1.3 relies on the HKDF-Extract and HKDF-Expand functions and the Hash function of the cipher suite.
Prior to the key exchange, the client and server use HKDF to generate the keys. (It replaces PRF, a pseudo-random key derivation function based on (H)MAC.)
To sign the keys that are exchanged during the initial handshake, TLS uses a signature algorithm. The signature algorithm takes a plaintext message (not a hash) and outputs a signature; any hashing is part of the signature algorithm.
TLS 1.3 allows the signature algorithms
- EdDSA (Edwards-curve Digital Signature Algorithm),
- ECDSA (Elliptic Curve Digital Signature Algorithm) and
- RSA (however, RSA is disallowed for the transport of keys!)
To confirm the identity of the server (and optionally, the client) during the TLS handshake, the protocol uses an authentication mechanism.
To confirm the authenticity of individual messages, the sender computes a message authentication code using (H)MAC.
The key exchange algorithm determines how the client and server authenticate during a TLS handshake. The key that they exchange may then be used with a symmetric encryption algorithm—the bulk cipher—to encrypt the actual data in the secure channel.
The secure TLS channel
In order to keep the communication a secret, TLS opens a secure channel in which all data sent and received is encrypted.
The secure channel relies on symmetric encryption: the encryption and the decryption keys are identical. Those keys have been exchanged during the TLS handshake in a procedure called TLS key exchange.
Ciphers and cipher suites
In cryptography, an algorithm that performs encryption or decryption is called a cipher (or cypher).
A cipher suite is a combination of such algorithms that provides a set of required features, namely key exchange, authentication, encryption (including the cipher and cipher mode) and message authentication (MAC).
The components of a cipher suite
TLS 1.3 separates the authentication and key exchange methods from the TLS record protection algorithm—the bulk cipher—and the hash function.
The bulk cipher algorithm uses symmetric encryption to secure the channel by encrypting and decrypting the transmission.
The bulk cipher
Bulk ciphers fall into one of two categories:
- stream ciphers operate on data one byte at a time (example: CHACHA20)
- block ciphers operate on blocks of data of equal length (example: AES) using a symmetric secret key.
An example of a cipher suite based on a safe stream cipher is TLS13-CHACHA20-POLY1305-SHA256 in TLS 1.3. (TLS 1.3 disallows the use of the stream cipher RC4.)
Examples of cipher suites based on a block cipher include TLS13-AES-128-GCM-SHA256 and TLS13-AES-256-GCM-SHA384 in TLS 1.3.
The MAC algorithm (short for Message Authentication Code) creates a message digest or a cryptographic hash of each message exchanged in the secure channel in order to ensure data integrity.
HMAC (Hashed Message Authentication Code) is a type of MAC involving a cryptographic hash function and a secret cryptographic key and is designed to simultaneously verify both the data integrity and the authenticity of a message in the secure channel. By using the session key as the HMAC key, the sender of a message can produce a hash of its payload in a way that cannot be forged by anyone unless they know the session key, thus allowing the client to verify its authenticity.
Collision resistance of the hash function
Cryptographic hash functions are public functions (they do not use a secret key) that offer collision-resistance. Collision resistance means that it is hard to find two messages with the same hash (a useful property for the purposes of authentication).
MACs are keyed functions that can counteract message forgery so long as the key remains a secret. HMAC is believed to retain the collision resistance of the underlying hash function even in the event that the MAC key is compromised.
MAC-then-Encrypt versus AEAD cipher suites
Since it is not sufficient to merely authenticate a message but also to prevent eavesdropping, the (H)MAC algorithm has to combine with the cipher that encrypts the payload. TLS 1.2 and its predecessors use a technique called MAC-then-Encrypt. The sender authenticates its plaintext message using a MAC algorithm, then encrypts the authenticated data. The recipient first decrypts the data using the session key, then verifies its authenticity. This approach has a major downside in that it allows an unauthenticated attacker to send arbitrary messages and force the receiving endpoint to decrypt garbage that would fail the MAC verification—a lot of work for nothing.
An Encrypt-then-MAC configuration would make a lot more sense. This technique first encrypts the message, then computes the MAC of the ciphertext so as to confirm its authenticity. As a result, the recipient can easily discard messages that don’t check out as authentic, since the attacker cannot forge the MAC without knowing the session key. Encrypt-then-Mac would close the padding oracle vulnerability. Unfortunately, Encrypt-then-MAC is notoriously difficult to implement.
The architects of TLS 1.3 opted for a third way: AEAD cipher suites. These cipher suites compute MAC and encrypt simultaneously, eliminating the padding oracle vulnerability—hopefully once and for all.
How to configure TLS for security (plus performance and compatibility)
TLS configuration involves quite a few steps. Here is what you need to do.
Step 1. Find out which cipher suites your server supports
The cipher suites that your system supports depend on the installed version of your cryptographic library.
Various crypto libraries such as OpenSSL, IANA and GnuTLS use slightly different names for the same cipher suites. Be careful when you edit you server’s configuration file. You want to use the correct syntax for your system.
To figure out the best parameters for your application, find out what cipher suites your system supports. With OpenSSL, use this command (or check the reference):
/usr/bin/openssl ciphers -s -v
The resulting list reveals the names of cipher suites and their capabilities:
- the protocol version (only TLS 1.3 and TLS 1.2 with certain cipher suites are considered trustworthy)
- key exchange algorithm (Diffie-Hellman, ECDH or Elliptic Curve Diffie-Hellman, SRP, PSK — do NOT use RSA!)
- authentication mechanism (DSA, ECDSA, RSA)
- bulk cipher (e.g. CHACHA20, AES128-GCM)
- cryptographic message authentication code (e.g. SHA384, POLY1305)
The general composition of the names of cipher suites in TLS 1.2 conforms to the logic:
Beware of abbreviated cipher suite designations. For example,
AES256-SHA256 will activate the insecure RSA algorithm (by implication) for both the key exchange and authentication, and use the vulnerable cipher mode CBC (Cipher Block chaining).
WARNING: Do NOT use RSA for the key exchange! Do NOT use the CBC block cipher mode, it’s been compromised time and time again. Avoid abbreviated naming conventions in cipher suites configuration unless you really know what you are doing.
Step 2. Activate cipher suites for TLS 1.3
TLS 1.3 requires that you specify the following AEAD (Authenticated Encryption with Associated Data) ciphers:
TLS13-CHACHA20-POLY1305-SHA256 TLS13-AES-256-GCM-SHA384 TLS13-AES-128-GCM-SHA256
You may tweak the order, but you should activate all three of the above.
For TLS 1.2, things are a bit more complicated.
Step 3. Configure TLS 1.2 with only the strongest cipher suites
When it comes to TLS 1.2, the quality of cipher suites varies greatly. This presents somewhat of a risk. Should even a single weak cipher suite find its way into your configuration, you would be in trouble.
In terms of the key exchange in TLS 1.2, you have two basic choices:
- ECDHE: an elliptic-curve Diffie-Hellman key exchange; it can be signed with either Elliptic Curve Digital Signature Algorithm ECDSA (ECDHE-ECDSA) or RSA (ECDHE-RSA). Either one is acceptable.
- DHE: a normal Diffie-Hellman key exchange.
Do NOT use RSA for the key exchange! (For example:
OpenSSL DES-CBC3-SHA, IANA TLS_RSA_WITH_3DES_EDE_CBC_SHA, are bad choices!)
DHE is slower than ECDHE. If you are concerned about performance, prioritize ECDHE-ECDSA over DHE. OWASP estimates that the TLS handshake with DHE hinders the CPU by a factor of 2.4 compared to ECDHE.
Top choices for secure ciphers
As of this writing, your first choice among TLS 1.2 cipher suites are the following ones (in OpenSSL syntax):
These somewhat older cipher suites are also acceptable:
ChaCha20/Poly1305 has somewhat of a performance advantage over AES on CPUs that don’t have a built-in support for AES (typically in mobile devices). Thus, your server should only opt for ChaCha20/Poly1305 when the client device declares such a preference. Otherwise, your server should use AES.
The above listed cipher suites may not suffice in terms of your clients’ compatibility requirements, though.
Additional cipher suites recommended for broader compatibility
If high compatibility with a variety of user agents is of concern, consider adding these cipher suites:
and finally these:
You will need to check these settings periodically to take advantage of future improvements. (It’s probably not what you wanted to hear, but as of now, vigilance is still a requirement for cyber security.)
Step 4. Test your setup
To test your web server setup, you can use Qualys Labs’ online SSL Server Test located at:
The tool simulates session negotiation with your web server by a variety of user agents. This way, you can see which of your select cipher suites are ordinarily in use so you can tweak your server’s configuration and discard cipher suites that are no longer in legitimate use.
TLS 1.3 final draft:
Pentest-Tools: Scan your server for the POODLE, DROWN, ROBOT, Bash Shellshock/Ghost, Heartbleed and more: