How TLS Protects Your Internet Connection: The Complete Guide

Understand how TLS (Transport Layer Security) combines symmetric encryption, asymmetric key exchange, and hash functions to protect every website visit, API call, and message you send online.

· 17 min read · Protocols

Every time you visit a website, send an API request, or receive a message, TLS (Transport Layer Security) is working silently in the background. The padlock icon in your browser’s address bar is its visible signal — but the cryptography behind it involves a sophisticated combination of every primitive we’ve covered across this blog.

TLS is not a single algorithm. It is a protocol orchestration that combines symmetric encryption, asymmetric key exchange, digital signatures, hash functions, and message authentication into a single handshake that completes in milliseconds. Understanding how TLS works means understanding how all these pieces fit together — and why each one is indispensable.

This guide walks through the TLS 1.3 handshake step by step, maps each phase to the cryptographic primitive it relies on, compares TLS 1.2 and 1.3, and gives you practical configuration guidance.

A Brief History: From SSL to TLS 1.3

Year Version Key Milestone
1994 SSL 1.0 Netscape’s first attempt (never publicly released)
1995 SSL 2.0 First public release; quickly found to have serious flaws
1996 SSL 3.0 Complete redesign; basis for all TLS versions
1999 TLS 1.0 IETF takes over; essentially SSL 3.1
2006 TLS 1.1 Added protection against CBC attacks
2008 TLS 1.2 SHA-2 cipher suites, AEAD modes, customizable PRFs
2018 TLS 1.3 1-RTT handshake, mandatory forward secrecy, removed all legacy algorithms

TLS 1.0 and 1.1 were deprecated by RFC 8996 in March 2021. TLS 1.2 remains widely used and is still considered secure when properly configured. TLS 1.3 is the current gold standard, supported by all major browsers and servers since 2018–2020.

The TLS Handshake: Phase by Phase

The TLS handshake is the process where two parties (typically a browser and a server) establish a secure connection. Think of it as a negotiation: “Here’s what I can do” → “Here’s what I think is best” → “Here’s proof I am who I say I am” → “Let’s start encrypting.”

Phase 1: Client Hello (The Opening Bid)

The client initiates the connection by sending:

  • Protocol version — disguised as TLS 1.2 (0x0303) for middlebox compatibility, with the real version (TLS 1.3 = 0x0304) in the supported_versions extension
  • 32 bytes of random data — the ClientRandom, used later in key derivation
  • Cipher suite list — in TLS 1.3, only three AEAD suites are defined:
    • TLS_AES_128_GCM_SHA256
    • TLS_AES_256_GCM_SHA384
    • TLS_CHACHA20_POLY1305_SHA256
  • Supported groups — elliptic curves for key exchange: X25519, P-256, P-384, P-521, X448, ffdhe2048–8192
  • Signature algorithms — ECDSA-P256-SHA256, Ed25519, RSA-PSS-SHA256, etc.
  • Key share — the client’s ephemeral public key (e.g., an X25519 public key, 32 bytes)
  • SNI (Server Name Indication) — the hostname the client wants to reach

Crypto primitives involved: Random number generation for ClientRandom, elliptic curve math for the key share.

Phase 2: Server Hello (The Response)

The server replies with:

  • Selected cipher suite — one from the client’s list (e.g., TLS_AES_256_GCM_SHA384)
  • 32 bytes of ServerRandom
  • Key share — the server’s ephemeral public key (same curve as the client’s)
  • Supported version — confirms TLS 1.3

At this point, both sides have each other’s ephemeral public keys. They can now compute a shared secret using elliptic curve Diffie-Hellman (ECDH).

Phase 3: Key Derivation (The Mathematical Magic)

This is where the real cryptography happens. Both client and server independently compute the same set of session keys — without ever transmitting them.

Step 1: Shared Secret via ECDH

Each side multiplies the other’s public key by their own private key on the agreed elliptic curve. Due to the properties of elliptic curve multiplication, both arrive at the same 32-byte shared secret:

shared_secret = ECDH(client_private, server_public)
             = ECDH(server_private, client_public)

This is the same math behind our ECC key generator and ECDH key exchange tool.

Step 2: HKDF Key Schedule

TLS 1.3 uses HKDF (HMAC-based Key Derivation Function, defined in RFC 5869) to derive all session keys from the shared secret. The process involves:

  1. early_secret = HKDF-Extract(salt: 0, key: 0) — initial extraction
  2. derived_secret = HKDF-Expand-Label(early_secret, "derived", empty_hash) — bridging to handshake
  3. handshake_secret = HKDF-Extract(derived_secret, shared_secret) — core secret
  4. client_hs_key = HKDF-Expand-Label(handshake_secret, "c hs traffic", hello_hash) — client handshake key
  5. server_hs_key = HKDF-Expand-Label(handshake_secret, "s hs traffic", hello_hash) — server handshake key

The HKDF is built on top of HMAC — the same primitive we cover in our HMAC guide. Each expansion step uses HMAC-SHA256 or HMAC-SHA384 depending on the cipher suite.

Step 3: Application Traffic Keys

After the handshake is verified, new keys are derived for actual data encryption:

application_secret = HKDF-Expand-Label(handshake_secret, "c ap traffic" / "s ap traffic", ...)
client_app_key = HKDF-Expand-Label(application_secret, "key", ...)
client_app_iv  = HKDF-Expand-Label(application_secret, "iv", ...)

These are the keys that encrypt your HTTP requests and responses.

Phase 4: Encrypted Handshake (Server Authentication)

From this point on, all remaining handshake messages are encrypted — a major improvement over TLS 1.2, where the server certificate was sent in the clear.

The server sends:

  1. EncryptedExtensions — non-critical extensions (hidden from eavesdroppers)
  2. Certificate — the server’s X.509 certificate chain (the same PEM format our PEM certificate parser can decode)
  3. CertificateVerify — a digital signature over the entire handshake transcript, proving the server possesses the private key corresponding to the certificate’s public key
  4. Finished — a MAC (message authentication code) over the entire handshake, ensuring no tampering occurred

The client verifies:

  • The certificate chain up to a trusted root CA
  • The CertificateVerify signature using the certificate’s public key
  • The Finished MAC

Crypto primitives involved: Digital signatures (RSA-PSS or Ed25519/ECDSA), SHA hashing for the transcript hash, HMAC for the Finished MAC.

Phase 5: Client Authentication (Optional)

In most web browsing, only the server is authenticated. But in mutual TLS (mTLS), the client also sends a certificate and CertificateVerify. This is common in API-to-API communication, zero-trust architectures, and enterprise environments.

Phase 6: Application Data

The handshake is complete. Both sides now use the negotiated symmetric cipher (AES-256-GCM, AES-128-GCM, or ChaCha20-Poly1305) to encrypt all application data. Each record is independently encrypted with a unique nonce derived from the IV and a sequence number.

Where Each Crypto Primitive Fits

Here’s the complete picture of how TLS combines every cryptographic primitive:

Phase Primitive TLS 1.3 Usage Our Tool
Client Hello Random generation ClientRandom (32 bytes) Random Bytes
Key Exchange Elliptic curve DH X25519 or P-256 key agreement ECC Key Gen / ECDH
Key Derivation HMAC / HKDF All key schedule operations HMAC Generator
Server Auth Digital signature CertificateVerify (RSA-PSS / Ed25519 / ECDSA) Digital Signature
Server Auth Hash function Transcript hash (SHA-256 / SHA-384) SHA Hash
Server Auth X.509 certificate Server identity proof CSR Generator / PEM Parser
Data Encryption AEAD cipher AES-256-GCM or ChaCha20-Poly1305 AES Encrypt

TLS is not a single algorithm — it is a symphony of every primitive we’ve discussed across this blog. If you understand AES, RSA, ECC, SHA, and HMAC individually, TLS is where they all come together.

TLS 1.2 vs TLS 1.3: What Changed

Feature TLS 1.2 (2008) TLS 1.3 (2018)
Handshake round trips 2-RTT (full) 1-RTT (full), 0-RTT (resumption)
Cipher suites 37+ (including RC4, 3DES, CBC) 3 (all AEAD)
Key exchange RSA, DH, ECDH, DHE, ECDHE ECDHE only (mandatory forward secrecy)
Handshake encryption Server cert sent in clear Entire handshake after ServerHello is encrypted
RSA key transport Supported Removed — breaks forward secrecy
CBC mode ciphers Supported Removed — vulnerable to padding oracle attacks
Compression Supported (vulnerable to CRIME) Removed
Renegotiation Supported (complex, risky) Removed
Static DH Supported Removed — no forward secrecy
Signature algorithms Negotiated implicitly Explicit signature_algorithms extension
PSK resumption Session IDs / tickets PSK with (EC)DHE or alone

The 1-RTT Handshake (TLS 1.3)

Client                                    Server
─────────────────────────────────────────────────────
ClientHello (key_share + supported_groups)
 ──────────────────────────────────────────→
                                    ServerHello (key_share)
                                    {EncryptedExtensions}
                                    {Certificate}
                                    {CertificateVerify}
                                    {Finished}
 ←──────────────────────────────────────────
{Client Finished}
 ──────────────────────────────────────────→
[Application Data] ←──────────────────────→ [Application Data]

Messages in {braces} are encrypted. The entire exchange after ServerHello is protected — an eavesdropper cannot see the server’s certificate or what algorithms were actually used.

The 0-RTT Resumption

If the client has connected to the server before, it can send data in the very first message using a Pre-Shared Key (PSK) from the previous session:

Client                                    Server
─────────────────────────────────────────────────────
ClientHello (key_share + PSK_identity + early_data)
[Early Application Data] ← sent immediately!
 ──────────────────────────────────────────→
                                    ServerHello (PSK acceptance)
                                    {EncryptedExtensions}
                                    ...
 ←──────────────────────────────────────────

Tradeoff: 0-RTT data is not forward secret — if the PSK is compromised, the early data can be decrypted. It is also vulnerable to replay attacks — an attacker can capture and retransmit the 0-RTT message. For this reason, 0-RTT is only safe for idempotent requests (GET, HEAD) and should never be used for state-changing operations like payments or password changes.

Forward Secrecy: Why It Matters

Forward secrecy (or perfect forward secrecy, PFS) means that compromising a long-term private key does not compromise past session keys.

In TLS 1.2 with static RSA key exchange, the server’s RSA private key was used to decrypt the pre-master secret sent by the client. If an attacker recorded encrypted traffic and later obtained the server’s RSA private key, they could decrypt all past sessions.

In TLS 1.3, all key exchange uses ephemeral ECDH. The server generates a fresh ECDH key pair for every single connection. Even if the server’s long-term signing key is compromised, past sessions remain secure because the ephemeral ECDH private keys were discarded immediately after use.

Scenario Static RSA (TLS 1.2) Ephemeral ECDH (TLS 1.3)
Server private key leaked All past sessions decryptable Past sessions remain secure
Recording + later key compromise Traffic exposed Traffic safe
Per-session key independence No Yes

This is why TLS 1.3 removed static RSA and static DH entirely — they cannot provide forward secrecy by design.

Cipher Suites in Detail

TLS 1.3 defines exactly three cipher suites. Each is an AEAD (Authenticated Encryption with Associated Data) algorithm:

TLS_AES_128_GCM_SHA256

  • Encryption: AES-128 in GCM mode
  • Key size: 128 bits
  • Nonce size: 96 bits (12 bytes)
  • Authentication tag: 128 bits
  • Hash: SHA-256 (for HKDF and transcript)
  • Security level: 128-bit
  • Best for: General-purpose web traffic; hardware-accelerated on most modern CPUs (AES-NI)

TLS_AES_256_GCM_SHA384

  • Encryption: AES-256 in GCM mode
  • Key size: 256 bits
  • Nonce size: 96 bits
  • Authentication tag: 128 bits
  • Hash: SHA-384
  • Security level: 256-bit
  • Best for: High-security applications; slightly slower than AES-128-GCM without hardware acceleration

TLS_CHACHA20_POLY1305_SHA256

  • Encryption: ChaCha20 stream cipher
  • Key size: 256 bits
  • Nonce size: 96 bits
  • Authentication: Poly1305 MAC (128-bit tag)
  • Hash: SHA-256
  • Security level: 256-bit
  • Best for: Devices without AES hardware acceleration (mobile phones, ARM servers); resistant to cache-timing attacks that affect AES

All three provide authenticated encryption — meaning they simultaneously encrypt data for confidentiality and generate an authentication tag for integrity. This eliminates the need for a separate HMAC on the data (unlike TLS 1.2’s CBC mode, which required encrypt-then-MAC or MAC-then-encrypt).

For a deep dive into the symmetric algorithms, see our guides on AES-256 encryption and understand how AES compares to ChaCha20 in performance and security characteristics.

Certificate Authentication: The Trust Chain

TLS 1.3 servers authenticate using X.509 certificates — the same certificates generated via our CSR generator and parseable by our PEM certificate parser.

The certificate chain works like this:

  1. End-entity certificate — contains the server’s public key and domain name, signed by a CA
  2. Intermediate CA certificate(s) — signed by the root CA, used to limit root CA exposure
  3. Root CA certificate — pre-installed in the client’s trust store (browser or OS)

The client verifies:

  • Each certificate’s signature using the issuer’s public key
  • Validity dates and domain names
  • Revocation status (via OCSP or CRL)
  • Certificate Transparency (CT) logs for public trust

Certificate Types

Type Validation Trust Level Use Case
DV (Domain Validated) Domain ownership only Basic Blogs, personal sites
OV (Organization Validated) Business identity + domain Medium Business websites
EV (Extended Validation) Rigorous business verification Highest Banking, e-commerce

For more on how certificates are requested and signed, see our guide on Certificate Signing Requests.

Practical TLS Configuration

Server-Side Recommendations

For nginx:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;  # Let the client choose
ssl_ecdh_curve X25519:secp256r1:secp384r1;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;

For Apache:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305
SSLHonorCipherOrder off

What to Avoid

Deprecated / Dangerous Why
TLS 1.0 / 1.1 No AEAD, vulnerable to BEAST, POODLE, Lucky13
RSA key exchange No forward secrecy
CBC mode ciphers Padding oracle vulnerabilities
RC4, 3DES, DES Known cryptographic weaknesses
SHA-1 for signatures Collision attacks demonstrated
Export-grade ciphers Intentionally weak (FREAK, Logjam)
Compression CRIME / BREACH attacks

Testing Your Configuration

  • SSL Labs Server Test — comprehensive grade (A+ to F) for your TLS setup
  • testssl.sh — command-line tool that checks for vulnerabilities and misconfigurations
  • cryptcheck.fr — quick grade-based assessment

TLS Beyond HTTPS

While HTTPS is the most visible use case, TLS also protects:

Protocol Over TLS? Description
HTTPS Yes (port 443) Web browsing
SMTPS Yes (port 465/587) Email submission
IMAPS Yes (port 993) Email retrieval
FTPS Yes (port 990) File transfer
MQTTS Yes (port 8883) IoT messaging
DNS over TLS Yes (port 853) Encrypted DNS resolution
DNS over HTTPS Yes (port 443) DNS within HTTPS
XMPP Optional Instant messaging
IRC Optional (port 6697) Chat

Quantum Threats to TLS

Current TLS 1.3 relies on two quantum-vulnerable primitives:

  1. ECDH key exchange — Shor’s algorithm on a sufficiently large quantum computer could compute the shared secret from the exchanged public keys
  2. RSA/ECDSA signatures — Shor’s algorithm could forge CertificateVerify signatures

Post-quantum TLS is being actively standardized:

  • ML-KEM (Kyber) for key exchange — replaces or supplements ECDH
  • ML-DSA (Dilithium) or SLH-DSA (SPHINCS+) for signatures — replaces RSA/ECDSA
  • Hybrid modes (e.g., X25519 + ML-KEM-768) provide dual security: even if one algorithm is broken, the other still protects the session

Major browsers (Chrome, Firefox) have already experimented with hybrid key exchange using X25519 + Kyber (now ML-KEM). See our Post-Quantum Cryptography guide for the full picture.

Troubleshooting Checklist

If your TLS connection is failing or showing warnings:

  • Certificate expired — check notAfter date in the server certificate
  • Wrong hostname — certificate CN/SAN must match the requested domain
  • Incomplete chain — server must send intermediate certificates (not just the leaf)
  • Protocol mismatch — client requires TLS 1.3 but server only supports TLS 1.2
  • Cipher suite mismatch — no common cipher suite between client and server
  • Revoked certificate — check OCSP stapling or CRL distribution
  • Self-signed certificate — client must explicitly trust the certificate or its CA
  • HSTS preload — if the domain is in the HSTS preload list, HTTP will be rejected

Frequently Asked Questions

What is the difference between TLS and SSL?

TLS (Transport Layer Security) is the successor to SSL (Secure Sockets Layer). SSL was the original protocol developed by Netscape in the 1990s. When the IETF standardized it, they renamed it TLS. TLS 1.0 was essentially SSL 3.1. All modern implementations use TLS — SSL 2.0 and 3.0 are deprecated and insecure. When people say “SSL certificate,” they actually mean a TLS certificate.

Does TLS use symmetric or asymmetric encryption?

Both. TLS uses asymmetric encryption (ECDH + digital signatures) during the handshake to securely exchange keys and authenticate identities. Then it switches to symmetric encryption (AES-GCM or ChaCha20-Poly1305) for the actual data transfer, because symmetric encryption is roughly 100–1000x faster for bulk data. This hybrid design gives you the best of both worlds: the key distribution advantages of asymmetric crypto and the performance of symmetric crypto.

What is forward secrecy and why does TLS 1.3 require it?

Forward secrecy means that even if a long-term private key is compromised in the future, past session keys remain secure. TLS 1.3 achieves this by using ephemeral ECDH for every connection — the server generates a fresh key pair each time and discards the private key after the session. This prevents an attacker who records encrypted traffic from decrypting it later, even if they obtain the server’s certificate private key.

What is 0-RTT and is it safe?

0-RTT (Zero Round-Trip Time) allows a returning client to send data in the very first message using a pre-shared key from a previous session. It reduces latency but comes with two caveats: (1) 0-RTT data is not forward secret, and (2) it is vulnerable to replay attacks — an attacker can capture and retransmit the 0-RTT message. Use 0-RTT only for idempotent requests like GET.

Which cipher suite should I prefer?

For most use cases, TLS_AES_256_GCM_SHA384 provides the strongest security. On mobile devices or CPUs without AES hardware acceleration, TLS_CHACHA20_POLY1305_SHA256 may be faster while still providing 256-bit security. TLS_AES_128_GCM_SHA256 is perfectly adequate for general web traffic and is the most commonly negotiated suite.

Can TLS 1.3 be broken by quantum computers?

Not yet — but a large enough quantum computer running Shor’s algorithm could break the ECDH key exchange and RSA/ECDSA signatures that TLS 1.3 relies on. The solution is post-quantum TLS using algorithms like ML-KEM (Kyber) for key exchange and ML-DSA (Dilithium) for signatures. Hybrid modes combining classical and post-quantum algorithms are already being tested in Chrome and Firefox.

Further Reading

Related Tools