Networking

How TLS Handshakes Work: The Cryptography Behind HTTPS

A step-by-step guide to TLS 1.3 handshakes covering key exchange, certificate chain validation, cipher suites, forward secrecy, and session resumption with 0-RTT.

A
Abhishek Patel10 min read

Infrastructure engineer with 10+ years building production systems on AWS, GCP,…

How TLS Handshakes Work: The Cryptography Behind HTTPS
How TLS Handshakes Work: The Cryptography Behind HTTPS

The Security Negotiation That Happens Before Every HTTPS Request

Every time your browser connects to an HTTPS site, a TLS handshake happens before a single byte of your actual data crosses the wire. This handshake negotiates encryption algorithms, verifies the server's identity, and derives the session keys that protect everything you send and receive. It takes 1-2 round trips and involves asymmetric cryptography, certificate chains, and key derivation functions -- all in under 100 milliseconds.

Most developers treat TLS as a black box: install a certificate, things work. But when something breaks -- certificate errors, handshake failures, performance problems -- you need to understand what's actually happening. This guide walks through the TLS 1.3 handshake step by step, explains the cryptographic primitives involved, and covers the failure modes you'll encounter in production.

What Is TLS?

Definition: TLS (Transport Layer Security) is a cryptographic protocol that provides confidentiality, integrity, and authentication for network communication. It sits between the transport layer (TCP) and the application layer (HTTP), encrypting data in transit using a combination of asymmetric and symmetric cryptography negotiated during the handshake.

TLS 1.3, standardized in 2018 (RFC 8446), stripped away the accumulated complexity of earlier versions. It removed insecure algorithms, reduced the handshake from 2 round trips to 1, and eliminated entire categories of attacks. If you're configuring a server today, TLS 1.3 should be your target.

Asymmetric vs Symmetric Encryption: The Key Distinction

TLS uses both types of cryptography, and understanding why is essential to understanding the handshake:

PropertyAsymmetric (Public Key)Symmetric
KeysPublic/private key pairSingle shared secret
SpeedSlow (1000x slower)Fast
Use in TLSKey exchange and authenticationBulk data encryption
AlgorithmsECDHE, RSA, Ed25519AES-128-GCM, ChaCha20-Poly1305

The handshake uses asymmetric crypto to establish a shared secret that both sides know but nobody else does. Then everything after the handshake uses fast symmetric encryption with that shared secret. It's the best of both worlds: the security of public key cryptography for key exchange, the speed of symmetric cryptography for data transfer.

The TLS 1.3 Handshake: Step by Step

  1. ClientHello -- The client sends supported TLS versions, cipher suites, and key shares (precomputed Diffie-Hellman public values). TLS 1.3 sends key shares upfront, which is why the handshake is one round trip faster than TLS 1.2.
  2. ServerHello -- The server picks the cipher suite, selects a key share, and sends its own Diffie-Hellman public value. At this point, both sides can compute the shared secret.
  3. Server Certificate -- The server sends its certificate chain. The client validates the chain up to a trusted root CA.
  4. CertificateVerify -- The server proves it owns the private key corresponding to the certificate by signing a hash of the handshake transcript.
  5. Server Finished -- The server sends a MAC (message authentication code) of the entire handshake, proving nothing was tampered with.
  6. Client Finished -- The client sends its own Finished message. The handshake is complete. Application data can flow.
Client                              Server
  |                                    |
  |--- ClientHello ------------------->|  (versions, cipher suites, key shares)
  |                                    |
  |<-- ServerHello --------------------|  (chosen cipher, key share)
  |<-- Certificate --------------------|  (certificate chain)
  |<-- CertificateVerify --------------|  (signature proving key ownership)
  |<-- Finished -----------------------|  (MAC of handshake)
  |                                    |
  |--- Finished ---------------------->|  (MAC of handshake)
  |                                    |
  |<== Encrypted Application Data ====>|  (symmetric encryption)
  |                                    |

Total: 1 round trip (TLS 1.3) vs 2 round trips (TLS 1.2)

Pro tip: Inspect a real TLS handshake with openssl s_client -connect example.com:443 -tls1_3. It prints every handshake message, the negotiated cipher suite, and the certificate chain. Add -msg for raw hex of each message.

Key Exchange: How Both Sides Agree on a Secret

TLS 1.3 uses Ephemeral Elliptic Curve Diffie-Hellman (ECDHE) for key exchange. Here's the mental model:

  1. The client generates a random private key and computes a public key on an elliptic curve (typically X25519 or P-256).
  2. The server does the same.
  3. Both sides exchange public keys in ClientHello/ServerHello.
  4. Each side combines their private key with the other's public key to compute the same shared secret -- without that secret ever crossing the wire.

The "ephemeral" part is critical: new keys are generated for every connection. If an attacker compromises the server's long-term private key later, they can't decrypt past sessions because the session keys were ephemeral and discarded. This property is called forward secrecy.

Certificate Chains and Validation

The certificate the server sends isn't just one certificate -- it's a chain:

  1. Leaf certificate -- Issued for your specific domain (e.g., techplained.com). Contains the server's public key.
  2. Intermediate certificate(s) -- Issued by a Certificate Authority (CA) to bridge between the leaf and the root. Most chains have 1-2 intermediates.
  3. Root certificate -- A self-signed certificate pre-installed in your operating system or browser's trust store. Not sent in the chain -- the client already has it.

Validation walks the chain from leaf to root, verifying each certificate's signature with its parent's public key. If the chain leads to a trusted root, the certificate is valid. The client also checks the domain name matches, the certificate hasn't expired, and it hasn't been revoked.

# View the full certificate chain
openssl s_client -connect techplained.com:443 -showcerts

# Check certificate expiration
echo | openssl s_client -connect techplained.com:443 2>/dev/null | openssl x509 -noout -dates

# Verify the chain explicitly
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt chain.pem

Watch out: The most common TLS error in production is a missing intermediate certificate. The leaf cert is valid, the root cert is trusted, but the server didn't send the intermediate that connects them. Browsers sometimes cache intermediates (which masks the problem), but API clients and mobile apps will reject the connection. Always test with openssl s_client, not just a browser.

Session Resumption and 0-RTT

A full handshake costs 1 round trip. For returning clients, TLS 1.3 offers two faster paths:

PSK Resumption (Pre-Shared Key)

After a successful handshake, the server sends a session ticket encrypted with a key only the server knows. On the next connection, the client includes this ticket in ClientHello. If the server recognizes it, both sides derive session keys from the PSK without a full key exchange. This still costs 1 RTT but skips certificate validation and some computation.

0-RTT Early Data

The client can send application data with the very first ClientHello packet, encrypted with keys derived from the PSK. The server processes this data before the handshake completes -- zero round trips of latency for the first request.

Watch out: 0-RTT data has no forward secrecy (it uses the PSK, not ephemeral keys) and is vulnerable to replay attacks. An attacker who captures the ClientHello can replay it, causing the server to process the early data again. Only use 0-RTT for idempotent requests like GET. Never for POST, PUT, or anything that changes state.

Cipher Suites in TLS 1.3

TLS 1.3 dramatically reduced the number of supported cipher suites from dozens to five:

Cipher SuiteKey ExchangeEncryptionNotes
TLS_AES_128_GCM_SHA256ECDHEAES-128-GCMMost common, hardware-accelerated on modern CPUs
TLS_AES_256_GCM_SHA384ECDHEAES-256-GCMHigher security margin, slightly slower
TLS_CHACHA20_POLY1305_SHA256ECDHEChaCha20-Poly1305Faster on devices without AES hardware (older mobile)
TLS_AES_128_CCM_SHA256ECDHEAES-128-CCMConstrained environments
TLS_AES_128_CCM_8_SHA256ECDHEAES-128-CCM-8IoT with limited bandwidth

All five use ECDHE for key exchange (forward secrecy is mandatory in TLS 1.3) and AEAD (authenticated encryption with associated data) for bulk encryption. The dangerous options from TLS 1.2 -- RSA key exchange, CBC mode, RC4, 3DES -- are gone entirely.

Certificate Providers: Cost Comparison

ProviderDV CertificateWildcardAutomation
Let's EncryptFreeFreeACME protocol (certbot)
CloudflareFree (with proxy)Free (with proxy)Automatic
AWS ACMFree (for AWS services)FreeAutomatic renewal
DigiCert$268/year$688/yearAPI available
Sectigo$76/year$250/yearAPI available

Pro tip: There's no security difference between a free Let's Encrypt certificate and a $268 DigiCert DV certificate. Both validate domain ownership and provide the same encryption. Paid certificates offer extended validation (EV), longer validity periods, and warranty -- but browsers have removed visual EV indicators, making the practical benefit minimal for most sites.

Frequently Asked Questions

What is the difference between TLS and SSL?

SSL (Secure Sockets Layer) is the predecessor to TLS. SSL 3.0 was the last SSL version, released in 1996. TLS 1.0 (1999) was effectively SSL 3.1 with security improvements. All SSL versions are now deprecated and insecure. When people say "SSL certificate," they mean a TLS certificate -- the name stuck even though the protocol changed. Use TLS 1.3 and disable everything older than TLS 1.2.

Why does TLS 1.3 only take 1 round trip?

TLS 1.2 required 2 round trips because the key exchange and cipher negotiation happened in separate messages after the initial hello. TLS 1.3 moves the client's key share into the ClientHello message, so the server has everything it needs to compute the shared secret immediately. The server responds with its key share, certificate, and Finished in a single flight.

What is forward secrecy and why does it matter?

Forward secrecy (also called perfect forward secrecy) means that compromising the server's long-term private key doesn't expose past encrypted sessions. TLS 1.3 achieves this by generating ephemeral Diffie-Hellman keys for every session. Even if an attacker records encrypted traffic and later obtains the server's private key, they can't derive the session keys because those were ephemeral and destroyed.

How do I check if my server supports TLS 1.3?

Run openssl s_client -connect yoursite.com:443 -tls1_3. If the connection succeeds, TLS 1.3 is supported. For a comprehensive scan, use testssl.sh or Qualys SSL Labs (ssllabs.com/ssltest) which grades your configuration and reports supported protocols, cipher suites, and common misconfigurations. Aim for an A+ rating.

Should I disable TLS 1.2?

Not yet for public-facing services. As of 2025, about 2-5% of clients can't negotiate TLS 1.3 -- older Android devices, legacy corporate systems, and some IoT devices. Support both TLS 1.2 and 1.3. For internal services where you control all clients, TLS 1.3-only is reasonable and simplifies your security posture. Disable TLS 1.0 and 1.1 immediately if you haven't already.

What causes "certificate not trusted" errors?

Three common causes: (1) Missing intermediate certificate -- the server sends the leaf cert but not the intermediates needed to chain to the root. Fix by configuring the full chain. (2) Expired certificate -- the cert's notAfter date has passed. Automate renewal with certbot or your cloud provider. (3) Wrong domain -- the certificate's Subject Alternative Names don't include the domain being accessed. Reissue with the correct domains.

Is HTTPS slower than HTTP?

The TLS handshake adds 1 round trip (TLS 1.3) of latency to the initial connection. For subsequent requests on the same connection, there's no additional overhead -- symmetric encryption on modern hardware adds less than 1% CPU overhead thanks to AES-NI instructions. With session resumption and HTTP/2 connection reuse, the practical performance impact is negligible. The security is worth it, and search engines penalize HTTP-only sites.

Conclusion

The TLS handshake is one of those things that works so well you forget it exists -- until a certificate expires at 3 AM. Use TLS 1.3, automate certificate renewal with Let's Encrypt or your cloud provider, and verify your configuration with SSL Labs. Make sure your server sends the complete certificate chain, not just the leaf. Enable HSTS to prevent protocol downgrade attacks. The cryptography is sound; the failures are almost always operational: expired certs, missing intermediates, or misconfigured cipher suites. Automate everything you can, and you'll rarely think about TLS again.

A

Written by

Abhishek Patel

Infrastructure engineer with 10+ years building production systems on AWS, GCP, and bare metal. Writes practical guides on cloud architecture, containers, networking, and Linux for developers who want to understand how things actually work under the hood.

Related Articles

Enjoyed this article?

Get more like this in your inbox. No spam, unsubscribe anytime.

Comments

Loading comments...

Leave a comment

Stay in the loop

New articles delivered to your inbox. No spam.