Almost every connection your organisation makes depends on TLS, yet most teams configure it by copying settings they cannot explain. Transport Layer Security (TLS) is the protocol that encrypts traffic between a client and a server, proves the server's identity with a certificate and detects tampering in transit. This guide explains, in plain language first, what happens during a TLS 1.3 handshake, how keys are agreed, how the certificate is checked and what a cipher suite actually is. It then goes deeper for practitioners: the differences between TLS 1.2 and 1.3, the risks of 0-RTT, the retirement of TLS 1.0 and 1.1, the status of hybrid post-quantum key exchange, and the configuration baselines in NIST SP 800-52 Rev. 2, RFC 9325 and the Mozilla guidelines. It is written for network, platform and application security engineers and anyone who has to sign off a TLS configuration.
Key takeaways
- TLS does three jobs at once: it agrees fresh session keys, authenticates the server (and optionally the client) with a certificate, and protects every record with authenticated encryption.
- TLS 1.3 is simpler and safer by design: RFC 8446 removed static RSA key exchange, compression and renegotiation, so every handshake has forward secrecy and completes in one round trip.
- The certificate check is where most real failures live: a client that skips chain or hostname validation gets encryption to whoever answers, which is no security at all.
- TLS 1.0 and 1.1 are formally dead: RFC 8996 says they "MUST NOT be used", and RFC 9325 makes TLS 1.2 mandatory and TLS 1.3 the preferred version.
- Post-quantum key exchange has arrived in TLS 1.3: RFC 10024 (August 2026) standardises hybrid groups such as X25519MLKEM768, which protect recorded traffic against future quantum decryption.
TLS in plain language
Imagine two people who have never met and must agree a secret over a crowded room where anyone can listen. TLS lets them do that. The client says hello and offers some maths it can do; the server picks one option, sends its half of the maths and a certificate that says who it is. Each side combines its own secret number with the other's public value and arrives at the same shared secret, which nobody listening can work out.
The certificate matters because the maths alone does not tell you who you are talking to. An attacker in the middle could run the same exchange with you. The certificate, signed by a certificate authority (CA) your device already trusts, binds the server's public key to its name. The server proves it holds the matching private key by signing the handshake. For the anatomy of certificates and CAs, see the PKI Basics Guide.
The TLS 1.3 handshake step by step
RFC 8446 defines a full handshake that completes in one round trip (1-RTT). The message flow is:
- ClientHello: the client sends a random value, the cipher suites it supports, the
supported_versionsextension,signature_algorithms, the Server Name Indication (SNI) and, crucially, akey_sharecontaining its ephemeral public key for one or more groups. It may also offer a pre-shared key (PSK) for resumption. - ServerHello: the server picks the version, cipher suite and group and returns its own
key_share. Both sides can now compute the shared secret, and everything after this point is encrypted. - EncryptedExtensions: remaining negotiated parameters, such as the ALPN protocol (h2 or http/1.1).
- CertificateRequest (optional): sent only when the server wants client authentication, which is the basis of mutual TLS; see the mTLS Guide.
- Certificate and CertificateVerify: the server's certificate chain, then a signature over the whole handshake transcript made with the certificate's private key. This proves possession of the key and binds it to this exact handshake.
- Finished: a MAC over the transcript from each side, which confirms that neither party's view of the handshake was altered.
If the client guessed the wrong group in its key_share, the server answers with a HelloRetryRequest naming the group it wants, and the client starts again; RFC 8446 notes that this first exchange is folded into the transcript. Application data must not be sent before Finished, except for 0-RTT early data described below. After a handshake the server can send a NewSessionTicket carrying a PSK identity, so a later connection can resume without a full certificate exchange; RFC 8446 recommends that resuming clients still send a key_share so the resumed session keeps forward secrecy (the psk_dhe_ke mode, which RFC 9325 also recommends).
Key exchange: ECDHE and forward secrecy
The key_share values are ephemeral elliptic curve Diffie-Hellman (ECDHE) public keys, generated fresh for each connection and discarded afterwards. Common groups are X25519, secp256r1 (P-256) and secp384r1 (P-384). Because the session keys come from ephemeral values, stealing the server's certificate private key later does not let an attacker decrypt traffic they recorded earlier. That property is forward secrecy. RFC 8446 states that static RSA and Diffie-Hellman suites were removed, so all TLS 1.3 public-key key exchange provides it. In TLS 1.2 it was optional: a server that negotiated a static RSA suite encrypted the premaster secret to its long-term key, so a single key compromise exposed every recorded session.
Certificates and chain validation
When the Certificate message arrives the client must do two separate checks, and both must pass:
- Path validation: build a chain from the leaf through intermediates to a root in the local trust store, checking signatures, validity dates, basic constraints, key usage and extended key usage (serverAuth), and revocation status where the client checks it. Servers must send the intermediates. The detail of path validation is in the PKI Basics Guide.
- Service identity: RFC 9525 (which obsoleted RFC 6125) says the hostname is matched against the subjectAltName dNSName entries, not the Common Name, and that a wildcard is allowed only as the whole left-most label (
*.example.commatchesapi.example.combut nota.b.example.com). On mismatch the client should end the connection.
Publicly trusted certificates must also be logged in Certificate Transparency before browsers accept them; see the Certificate Transparency Guide. Lifetimes for public certificates are falling to 47 days, covered in the Certificate Expiry Outages and 47-Day TLS Certificates Guide.
Cipher suites explained
A cipher suite names the algorithms a connection uses. In TLS 1.2 the name bundled four choices: key exchange, authentication, bulk cipher and hash, for example TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ECDHE key exchange, RSA certificate, AES-128 in GCM mode, SHA-256 for the PRF). TLS 1.3 separated these: the suite names only the AEAD cipher and the hash used for key derivation, while the key exchange group and the signature algorithm are negotiated in their own extensions. TLS 1.3 defines five suites; only AEAD algorithms remain.
| TLS 1.3 suite | Cipher | Typical use |
|---|---|---|
| TLS_AES_128_GCM_SHA256 | AES-128-GCM | Default everywhere; fast with AES hardware instructions |
| TLS_AES_256_GCM_SHA384 | AES-256-GCM | Where policy requires 256-bit keys |
| TLS_CHACHA20_POLY1305_SHA256 | ChaCha20-Poly1305 | Mobile and devices without AES acceleration |
| TLS_AES_128_CCM_SHA256 | AES-128-CCM | Constrained and IoT profiles |
| TLS_AES_128_CCM_8_SHA256 | AES-128-CCM with 8-byte tag | Constrained devices only; not in general web baselines |
The Mozilla guidelines (version 5.7) enable only the first three for TLS 1.3. For TLS 1.2, RFC 9325 recommends the four ECDHE AES-GCM suites (ECDHE_RSA and ECDHE_ECDSA with AES_128_GCM_SHA256 and AES_256_GCM_SHA384), says never to negotiate NULL, RC4 or anything under 112 bits of security, to avoid suites without forward secrecy, to avoid TLS 1.2 DHE suites and to avoid CBC suites unless Encrypt-then-MAC is negotiated. It sets minimums of 2048-bit DH and RSA keys and forbids SHA-1 and MD5 in signatures.
TLS 1.2 compared with TLS 1.3
TLS 1.2 is still widely deployed and remains acceptable when configured well, but it carries options that TLS 1.3 deleted. The practical differences:
| Aspect | TLS 1.2 (RFC 5246) | TLS 1.3 (RFC 8446) |
|---|---|---|
| Round trips for a full handshake | 2-RTT | 1-RTT; 0-RTT possible on resumption |
| Key exchange | Static RSA, DHE or ECDHE | (EC)DHE or PSK with (EC)DHE only; forward secrecy always for certificate handshakes |
| Handshake encryption | Certificate sent in clear | Everything after ServerHello encrypted, including the certificate |
| Ciphers | CBC, RC4, 3DES and AEAD all possible | AEAD only (five suites) |
| Renegotiation | Allowed (needs renegotiation_info) | Removed; KeyUpdate refreshes traffic keys instead |
| Compression | Possible (CRIME class attacks) | Removed |
| Version negotiation | Version field in hello | supported_versions extension, plus a downgrade sentinel |
| Resumption | Session IDs and session tickets | One PSK mechanism |
Downgrade protection: a TLS 1.3 server that is forced to negotiate an older version writes a fixed sentinel into the last eight bytes of ServerHello.random (44 4F 57 4E 47 52 44 01 for TLS 1.2, ending 00 for 1.1 and below). A TLS 1.3 client that sees it aborts. This blunts the active downgrade attacks that ATT&CK tracks as T1689 Downgrade Attack. If you still need TLS 1.2 hardening, RFC 9325 asks for extended_master_secret, the renegotiation_info extension and weekly rotation of session ticket keys.
0-RTT early data and its replay risk
TLS 1.3 lets a resuming client send application data in its first flight, encrypted under the PSK from an earlier session. This saves a round trip, but RFC 8446 is explicit that early data is weaker: it is "not forward secret, as it is encrypted solely under keys derived using the offered PSK", and "There are no guarantees of non-replay between connections." An attacker who captures a ClientHello with early data can resend it to the server, and the request is processed again.
- Default stance: RFC 9325 says to avoid 0-RTT unless an application protocol profile makes it appropriate. Leave it off unless you have measured a latency need.
- If you enable it, limit what it carries: RFC 8470 says clients "MUST NOT send unsafe methods (or methods whose safety is not known) in early data". Accept only safe, side-effect-free requests (GET of static or cacheable content), never POST, payments, logins or state changes.
- Use the HTTP signals: intermediaries that forward early-data requests set
Early-Data: 1; origin servers that judge a request unsafe reply425 Too Early, and the client retries after the handshake completes. - Server-side anti-replay: RFC 8446 Section 8 describes single-use tickets, recording ClientHello values within a time window and freshness checks on the ticket age. In a cluster these need shared state.
Retired versions and current baselines
RFC 8996 (March 2021, part of BCP 195) moved TLS 1.0 and 1.1 to Historic status and says each "MUST NOT be used", and that negotiation of them from any version "MUST NOT be permitted". Its reasons include handshake integrity that depends on SHA-1, no support for AEAD ciphers, and the misconfiguration risk of supporting four versions. It also marked TLS_FALLBACK_SCSV (RFC 7507) obsolete. RFC 9325 (November 2022) now states the baseline: support TLS 1.2, support and prefer TLS 1.3, support SNI and ALPN, use HSTS, staple OCSP where available.
NIST SP 800-52 Rev. 2 (August 2019) applies to US federal systems and is a useful benchmark elsewhere: servers and clients support TLS 1.2 with FIPS-based cipher suites, and support for TLS 1.3 was required by 1 January 2024. NIST's page carries a planning note from May 2026 that the publication is under review, so check it before citing it in a policy.
Mozilla configuration profiles: the Mozilla Server Side TLS wiki page now redirects readers to a community working group (docs.tlsref.org), while the machine-readable guidelines behind the Mozilla SSL Configuration Generator remain the most practical starting point.
| Profile (guidelines 5.7) | Protocols | Certificate | Oldest clients supported | When to choose |
|---|---|---|---|---|
| Modern | TLS 1.3 only; groups X25519, P-256, P-384 | ECDSA P-256 or P-384, 90-day lifespan | Firefox 63, Chrome 70, Safari 12.1, Android 10, Java 11, OpenSSL 1.1.1 | Internal services and APIs where you control every client |
| Intermediate | TLS 1.2 and 1.3; ECDHE (and DHE) with AES-GCM or ChaCha20-Poly1305 | ECDSA or RSA 2048, 90 days recommended, 366 maximum | Firefox 27, Chrome 31, IE 11 on Windows 7, Android 4.4.2, Java 8u31 | Default for public websites and general-purpose servers |
| Old | TLS 1.0 to 1.3, CBC and 3DES suites | RSA 2048 | IE8 on Windows XP, Java 6 | Only for a documented legacy dependency, isolated and time-boxed; conflicts with RFC 8996 |
All three profiles set HSTS max-age to 63072000 seconds (two years).
Hybrid post-quantum key exchange
A sufficiently capable quantum computer would break ECDHE, so traffic recorded today could be decrypted later. The defence is to add a post-quantum key encapsulation mechanism to the key exchange. NIST standardised ML-KEM in FIPS 203 (13 August 2024) with parameter sets ML-KEM-512, 768 and 1024. The IETF draft draft-ietf-tls-ecdhe-mlkem was published in August 2026 as RFC 10024, "Post-Quantum Traditional (PQ/T) Hybrid Key Agreement Mechanisms for TLS 1.3", a Standards Track document.
- Groups: X25519MLKEM768 (codepoint 0x11EC, marked Recommended), SecP256r1MLKEM768 (0x11EB) and SecP384r1MLKEM1024 (0x11ED). Each combines a classical ECDHE share with an ML-KEM share, so the connection stays secure if either component holds.
- Size: an X25519MLKEM768 client key share is 1,216 bytes, compared with 32 bytes for plain X25519. ClientHellos therefore often span more than one TCP packet, which has broken some middleboxes and load balancers that assume a single-packet hello.
- Retire the drafts: RFC 10024 obsoletes the pre-standard X25519Kyber768Draft00 codepoints, so remove them from configurations that enabled them during testing.
- Signatures are a separate step: hybrid key exchange protects confidentiality now; certificate signatures with post-quantum algorithms are a later, harder migration. Treat it as part of the programme in the Post-Quantum Cryptography Migration Guide and the Crypto-Agility Guide.
Choosing a configuration
- Public website or API with unknown clients: Intermediate profile, TLS 1.2 and 1.3, ECDSA certificate (add RSA as a second certificate only if logs show RSA-only clients), HSTS, 0-RTT off.
- Service-to-service inside your estate: TLS 1.3 only (Modern), which removes most configuration choices. Add client certificates where you need workload identity.
- Regulated or federal workloads: follow SP 800-52 Rev. 2 and use a FIPS 140-validated module; this narrows suites to AES-GCM and the NIST curves.
- Legacy devices that cannot do TLS 1.2: do not lower the main endpoint. Put a separate listener or gateway in front of the legacy population, restrict it by network, log it and set a retirement date.
- Small versus large organisations: small teams should use managed TLS at a CDN or cloud load balancer with a TLS 1.2 minimum; large estates need a central baseline, a scanner across every listener and an owner for each exception. Each termination point, including inspection proxies (see the TLS Inspection Guide), holds a private key and sees plaintext.
Where identity fits
A TLS private key is a machine credential: whoever holds it can impersonate the service. Treat server keys as non-human identities with an owner, an inventory entry, restricted file permissions or hardware protection (HSM, cloud KMS, TPM) and automated rotation. Stolen or forged certificates map to ATT&CK T1649 Steal or Forge Authentication Certificates. In mTLS the client certificate becomes the workload's identity, so issuance and revocation belong in your identity governance. See the Machine Identity, PKI and Certificate Lifecycle Guide and the Cryptographic Key Management Guide.
Rolling out a TLS baseline
- Inventory listeners: scan every external and internal IP and port for TLS (443, 8443, 636, 993, 465, 587 STARTTLS, database ports) and record version, suites, groups, certificate and owner.
- Measure clients before changing servers: enable logging of negotiated version and cipher on load balancers and web servers for two to four weeks, so you know who still uses TLS 1.0, 1.1 or CBC suites.
- Set the standard: adopt Intermediate as the default and Modern for internal services, written as a configuration baseline in your CM tooling.
- Pilot: apply to a low-risk service, then a ring of internal services, watching handshake failure rates and alert counts (
protocol_version,handshake_failure). - Disable old versions: turn off TLS 1.0 and 1.1 and non-AEAD suites, with legacy clients moved to an isolated exception listener first.
- Add TLS 1.3 features carefully: enable TLS 1.3 everywhere, then hybrid post-quantum groups where libraries support them; keep 0-RTT disabled unless justified.
- Roll back safely: keep the previous configuration in version control and change one listener group at a time, so a rollback is a redeploy rather than an emergency edit.
Detection and measurement
- Log negotiated parameters: TLS version, cipher suite, group and SNI on load balancers, reverse proxies and web servers (for example the
$ssl_protocoland$ssl_ciphervariables in nginx), sent to the SIEM. - Watch for downgrades and failures: sudden increases in TLS 1.2 or handshake failures from a client population can mean a broken middlebox or an active downgrade or interception attempt (T1557 Adversary-in-the-Middle).
- Check validation in clients: code review and SAST rules for disabled verification (
verify=False,InsecureSkipVerify: true, trust-all TrustManagers).
Metrics that show the baseline is working:
- Percentage of listeners compliant with the baseline profile (target 100% outside documented exceptions).
- Share of connections negotiated with TLS 1.3, tracked monthly.
- Number of endpoints still accepting TLS 1.0 or 1.1, or non-AEAD suites (target zero).
- Share of TLS 1.3 connections using a hybrid post-quantum group.
- Code findings for disabled certificate verification, open and fixed.
Framework mapping
| Framework | Reference | How this guide applies |
|---|---|---|
| NIST CSF 2.0 | PR.DS-02 | Data in transit protected with TLS 1.2 or later |
| NIST CSF 2.0 | PR.PS-01 | TLS baseline managed as configuration |
| NIST SP 800-53 Rev. 5 | SC-8, SC-8(1) | Transmission confidentiality and integrity with cryptographic protection |
| NIST SP 800-53 Rev. 5 | SC-12, SC-13, SC-17 | Key establishment, approved cryptography, PKI certificates |
| NIST SP 800-53 Rev. 5 | SC-23 | Session authenticity, including protection against replay |
| CIS Controls v8.1 | 3.10 | Encrypt sensitive data in transit |
| ISO/IEC 27001:2022 | A.8.24 | Use of cryptography |
| MITRE ATT&CK | T1557, T1689, T1040, T1649 | Interception, downgrade, sniffing and certificate theft that TLS controls address |
Common failure patterns
- Certificate verification turned off in code: a developer disables validation to get past a test error and it ships, so the client encrypts to any interceptor.
- Missing intermediate certificates: browsers that cache intermediates work while API clients, Java and IoT devices fail, which leads teams to weaken validation instead of fixing the chain.
- Legacy versions kept "just in case": TLS 1.0 stays enabled on one listener for a forgotten client, and scanners and auditors find it first.
- 0-RTT enabled by default: a CDN or server enables early data and non-idempotent requests become replayable.
- Private keys copied everywhere: the same key and wildcard certificate sit on dozens of hosts, so one compromise exposes them all and rotation becomes an outage risk.
Practitioner checklist
- Inventory every TLS listener, internal and external, with an owner and its negotiated settings.
- Disable SSL 3.0, TLS 1.0 and TLS 1.1 everywhere; isolate any legacy exception with a retirement date.
- Adopt the Intermediate profile as the default and TLS 1.3 only for internal services.
- Use only AEAD suites with ECDHE; remove static RSA, CBC without Encrypt-then-MAC, RC4 and 3DES.
- Serve the full chain and confirm clients validate both the chain and the subjectAltName hostname.
- Keep 0-RTT disabled unless a reviewed use case limits it to safe requests and handles
425 Too Early. - Enable HSTS on web properties and staple OCSP where your CA still provides it.
- Test and enable X25519MLKEM768 where libraries and network paths support it, keeping a classical fallback.
- Protect server private keys as machine identities: restricted access, HSM or KMS where possible, automated rotation.
- Log version and cipher per connection and review the metrics monthly.
Standards and references
- IETF: RFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3
- IETF: RFC 9325, Recommendations for Secure Use of TLS and DTLS (BCP 195)
- IETF: RFC 8996, Deprecating TLS 1.0 and TLS 1.1
- IETF: RFC 10024, Post-Quantum Traditional (PQ/T) Hybrid Key Agreement Mechanisms for TLS 1.3
- NIST: SP 800-52 Rev. 2, Guidelines for the Selection, Configuration, and Use of TLS Implementations
- NIST: FIPS 203, Module-Lattice-Based Key-Encapsulation Mechanism Standard
- Mozilla: Server Side TLS guidelines 5.7
- IETF: RFC 8470, Using Early Data in HTTP
Related NHI Mgmt Group resources: PKI Basics Guide · mTLS Guide · TLS Inspection Guide · Certificate Transparency Guide · Cryptography Basics Guide