Basics

TLS cipher suites explained: names, AEAD and safe choices

By · Last verified

A cipher suite is the named set of algorithms a TLS connection uses. A TLS 1.2 name lists the key exchange, authentication, bulk cipher and hash; a TLS 1.3 name lists only the AEAD cipher and key-derivation hash, and there are five. As of November 2026, enable the TLS 1.3 defaults plus TLS 1.2 ECDHE suites with AES-GCM or ChaCha20-Poly1305.

Anatomy of a TLS 1.2 cipher suite name

A TLS 1.2 suite name is a sentence with four slots, and reading it tells you exactly what the connection will do.

TLS _ ECDHE _ RSA _ WITH _ AES_128_GCM _ SHA256
      |       |            |             |
      |       |            |             +-- hash for the PRF (and the HMAC in CBC suites)
      |       |            +---------------- bulk cipher, key size and mode
      |       +----------------------------- authentication: the certificate's key type
      +------------------------------------- key exchange
Slot Common values What it decides
Key exchange ECDHE, DHE, RSA How the shared secret is created; only ephemeral (EC)DHE gives forward secrecy
Authentication RSA, ECDSA Which certificate key type can be used
Bulk cipher AES_128_GCM, AES_256_GCM, CHACHA20_POLY1305, AES_128_CBC, 3DES_EDE_CBC How records are encrypted
Hash SHA256, SHA384, SHA (SHA-1) The TLS PRF; in CBC suites also the record MAC

When the key exchange and authentication are the same algorithm, the name collapses: TLS_RSA_WITH_AES_128_CBC_SHA means RSA key transport and RSA authentication, with no ephemeral key at all.

OpenSSL uses its own shorter names. openssl ciphers -stdname prints both:

openssl ciphers -stdname 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-SHA'
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA    - ECDHE-RSA-AES128-SHA        TLSv1   Kx=ECDH Au=RSA Enc=AES(128)    Mac=SHA1
TLS_RSA_WITH_AES_128_CBC_SHA          - AES128-SHA                  SSLv3   Kx=RSA  Au=RSA Enc=AES(128)    Mac=SHA1

(The three TLS 1.3 lines OpenSSL always prints first are omitted here.) The TLSv1 and SSLv3 columns show the oldest protocol version a suite exists in, which is a quick hint that it is a legacy suite.

TLS 1.3: five suites and nothing else

TLS 1.3 removed key exchange and authentication from the suite name. Key exchange is negotiated through supported_groups and key_share, signatures through signature_algorithms, and the cipher suite only picks the AEAD and the HKDF hash.

Code Name Status in RFC 9846 (same as RFC 8446) Enabled by default in OpenSSL 3.x
0x1301 TLS_AES_128_GCM_SHA256 Mandatory to implement Yes
0x1302 TLS_AES_256_GCM_SHA384 Should implement Yes
0x1303 TLS_CHACHA20_POLY1305_SHA256 Should implement Yes
0x1304 TLS_AES_128_CCM_SHA256 Optional No
0x1305 TLS_AES_128_CCM_8_SHA256 Optional, short 8-byte tag No

This change ended the combinatorial explosion of TLS 1.2, where the IANA registry accumulated hundreds of code points for every combination of exchange, signature, cipher and hash. It also means a TLS 1.3 suite name tells you nothing about whether the key exchange was X25519, P-256 or the hybrid X25519MLKEM768; tools report the group separately, for example Negotiated TLS1.3 group: X25519MLKEM768 in openssl s_client -brief.

The July 2026 revision of TLS 1.3, RFC 9846, keeps the version number 0x0304 and the same five suites. Among its clarifications, it describes the key exchange in more generic language than the original RFC 8446, so that KEM-based key exchange such as ML-KEM fits the specification.

The two CCM suites exist for constrained devices. QUIC (RFC 9001) forbids TLS_AES_128_CCM_8_SHA256 because its 8-byte tag is too short for general use.

How a suite gets negotiated

The client proposes and the server decides. The ClientHello carries the client's full list of suites in preference order; the server picks one it also supports and names it in ServerHello. If there is no overlap, the server sends a handshake_failure alert.

In TLS 1.2 that single choice drags other constraints along:

  • An ECDHE_ECDSA suite can only be picked if the server has an ECDSA certificate, and an ECDHE_RSA suite needs an RSA certificate.
  • The ECDHE curve comes from the client's supported_groups extension, so a suite can be acceptable while no common curve exists.
  • The signature over the ServerKeyExchange must use a hash the client listed in signature_algorithms.

In TLS 1.3 these three decisions are independent. The server picks an AEAD suite, a group from key_share (or asks for another one with HelloRetryRequest), and a signature scheme that matches its certificate, each from its own list. That is why adding a post-quantum group or an Ed25519 certificate does not require new cipher suites.

On the client side you often cannot edit the list directly. Browsers ship fixed lists that change with releases. Java reads jdk.tls.disabledAlgorithms from its java.security file, Windows Schannel takes its order from Group Policy or PowerShell (Get-TlsCipherSuite), and curl or Python inherit the defaults of the TLS library they are linked against. When an internal client fails against a hardened server, check which library and version it uses before touching the server.

AEAD: why every modern suite uses it

AEAD (Authenticated Encryption with Associated Data) encrypts and authenticates in a single primitive, and TLS 1.3 allows nothing else. The three AEADs you will see are AES-GCM, ChaCha20-Poly1305 (RFC 7905) and AES-CCM.

Older TLS used CBC mode with a separate HMAC in a "MAC-then-encrypt" order. That construction leaked information through padding checks and timing, producing a decade of attacks: BEAST (2011) against TLS 1.0's predictable IVs, Lucky Thirteen (2013) timing attacks on CBC padding, and POODLE (2014) against SSL 3.0. AEAD modes have no padding oracle to attack. ChaCha20-Poly1305 is also fast in pure software, which is why phones and small ARM devices without AES instructions prefer it. See AEAD.

Forward secrecy and the key exchange slot

Only suites whose key exchange starts with ECDHE or DHE provide forward secrecy. With the static RSA key exchange, the client encrypts the pre-master secret to the server's certificate key, so anyone who later obtains that private key can decrypt every recorded session.

Key exchange Forward secrecy Status
RSA (key transport) No Remove; also exposed to padding-oracle attacks such as ROBOT (2017)
DHE (finite field) Yes Slow and only safe with 2048-bit+ groups; dropped from Mozilla's 6.0 recommendations
ECDHE Yes Recommended for TLS 1.2
TLS 1.3 (EC)DHE / hybrid Yes Always used, except pure-PSK resumption

One caveat: session tickets are encrypted with a server-side ticket key. If that key lives for months and leaks, resumed sessions can be decrypted. Rotate ticket keys regularly or disable tickets on servers where you cannot.

What to disable and why

Anything without AEAD, without forward secrecy, or with a broken primitive should be off. The table lists what you still find on legacy servers:

Family Example (OpenSSL name) Problem
NULL NULL-SHA256 No encryption at all
Anonymous ADH-AES128-SHA No authentication; trivial man-in-the-middle
Export EXP-RC4-MD5 Deliberately weakened 40/56-bit keys; FREAK and Logjam (2015)
RC4 RC4-SHA Statistical biases; prohibited by RFC 7465 (2015)
DES / 3DES DES-CBC3-SHA 64-bit blocks; Sweet32 (2016) finds collisions after about 2^32 blocks (32 GB)
CBC with SHA-1 ECDHE-RSA-AES128-SHA MAC-then-encrypt padding and timing issues
Static RSA AES128-GCM-SHA256 No forward secrecy
CCM_8 TLS_AES_128_CCM_8_SHA256 Short tag; not for general web use

Modern OpenSSL builds already exclude the worst of these. With OpenSSL 3.6, openssl ciphers -v 'RC4' and openssl ciphers -v '3DES' both return "no cipher match". RFC 9325 (BCP 195, November 2022) lists the suites the IETF currently recommends for TLS 1.2, which match the ECDHE plus AEAD list below.

For a public server, follow Mozilla's intermediate profile: TLS 1.2 and 1.3, with six ECDHE suites for TLS 1.2. Mozilla's guidelines are the de facto reference, and version 6.0, current as of November 2026, defines two profiles:

  • Modern: TLS 1.3 only, with TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384 and TLS_CHACHA20_POLY1305_SHA256. Oldest compatible clients include Firefox 63, Chrome 70, Safari 12.1, Android 10 and Java 11.
  • Intermediate: TLS 1.2 and 1.3. For TLS 1.2 it allows exactly six suites: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-ECDSA-CHACHA20-POLY1305 and ECDHE-RSA-CHACHA20-POLY1305. Groups are X25519MLKEM768, X25519, prime256v1 and secp384r1, and server_preferred_order is false.

Compared with version 5.7, 6.0 dropped the three DHE suites and added the post-quantum hybrid group. An nginx server block following the intermediate profile:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# X25519MLKEM768 needs nginx linked against OpenSSL 3.5 or later
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1:secp384r1;

ssl_ciphers only affects TLS 1.2 and below. TLS 1.3 suites come from OpenSSL's defaults, which are already the right three; to change them, nginx 1.19.4 and later accept ssl_conf_command Ciphersuites .... If nginx is linked against an OpenSSL older than 3.5, drop X25519MLKEM768 from the curve list or nginx will refuse to start.

The Apache equivalent uses the protocol prefix for TLS 1.3:

SSLProtocol             -all +TLSv1.2 +TLSv1.3
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
SSLCipherSuite TLSv1.3  TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
SSLHonorCipherOrder     off

Notice that every TLS 1.2 suite appears twice, once for ECDSA and once for RSA certificates. A server can hold both certificate types and serve each client the one it supports. The TLS config generator produces these snippets for other servers.

Inspecting and testing suites with OpenSSL

openssl ciphers -v expands a cipher string into the exact suites it selects, so you can review a config before deploying it:

openssl ciphers -v 'ECDHE+AESGCM:ECDHE+CHACHA20' | grep TLSv1.2
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128)            Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2 Kx=ECDH     Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD

To check what a live server accepts, force one suite at a time with s_client: -cipher for TLS 1.2 and below, -ciphersuites for TLS 1.3.

# Does the server still accept a CBC suite over TLS 1.2?
openssl s_client -connect example.com:443 -tls1_2 -cipher ECDHE-RSA-AES128-SHA </dev/null
# Does it accept ChaCha20 over TLS 1.3?
openssl s_client -connect example.com:443 -tls1_3 -ciphersuites TLS_CHACHA20_POLY1305_SHA256 </dev/null

A handshake failure alert means the suite is disabled. The cipher and protocol cookbook has a loop that tests every suite, and the cipher suite lookup decodes any IANA or OpenSSL name.

Preference order and performance

With only strong suites enabled, order matters for performance rather than security. Clients list suites in their own preference; browsers on phones without AES acceleration put ChaCha20-Poly1305 first. If the server enforces its own order with AES-GCM first, those devices lose the faster cipher, which is why Mozilla now recommends letting the client choose. OpenSSL also has a PrioritizeChaCha option that keeps the server's order but honors a client that lists ChaCha20 first.

If a client and server share no suite at all, the handshake fails, and Chrome shows ERR_SSL_VERSION_OR_CIPHER_MISMATCH. That usually means a server restricted to TLS 1.3 or exotic suites met an old client, or a legacy client only speaking 3DES or RC4 met a modern server. Fix the server list instead of re-enabling broken suites when you can.

FAQ

Which cipher suites should I enable in 2026?

For most public sites: TLS 1.3 with its default suites, plus TLS 1.2 limited to ECDHE key exchange with AES-GCM or ChaCha20-Poly1305. That is Mozilla's "intermediate" profile (guidelines 6.0). If every client supports TLS 1.3, the "modern" profile (TLS 1.3 only) is simpler.

Is AES-256 safer than AES-128 for TLS?

Both are considered secure as of November 2026. AES-128-GCM is slightly faster and is the one TLS 1.3 makes mandatory to implement. AES-256 gives extra margin, including against future quantum attacks on symmetric keys, so many servers offer both and let clients choose.

Why does openssl ciphers show TLS 1.3 suites I did not ask for?

OpenSSL configures TLS 1.3 suites separately (the -ciphersuites option or the Ciphersuites setting), and openssl ciphers always appends them to the list it prints. Use -tls1_2 or check only the TLSv1.2 lines when reviewing a cipher string.

Should the server or the client choose the cipher order?

With a list that contains only strong AEAD suites, letting the client choose is fine and helps phones pick ChaCha20-Poly1305 when they lack AES hardware. Mozilla's 6.0 guidelines set server_preferred_order to false, which in nginx is ssl_prefer_server_ciphers off.

Sources

  1. RFC 9846: TLS 1.3 (July 2026), section 9.1 and appendix B.4
  2. RFC 9325: Recommendations for Secure Use of TLS and DTLS (BCP 195)
  3. RFC 7465: Prohibiting RC4 Cipher Suites
  4. RFC 7905: ChaCha20-Poly1305 Cipher Suites for TLS
  5. Mozilla wiki: Security/Server Side TLS
  6. Mozilla SSL Configuration Generator
  7. IANA: TLS Cipher Suites registry
  8. OpenSSL documentation: openssl-ciphers