~/learn / web-fundamentals / tls
TLS and Certificates
What the padlock actually guarantees, how the TLS 1.3 handshake and certificate chain work, what a cipher suite and forward secrecy mean, the 0-RTT replay tradeoff, and the misconfigurations worth checking.
TLS, Transport Layer Security, is the S in HTTPS. It gives a connection three properties:
- Confidentiality. Nobody between you and the server can read the traffic.
- Integrity. Nobody can change it undetected.
- Authentication. You are talking to the server that owns the name you typed.
What it does not guarantee: that the site is honest, safe, or bug-free. A phishing site can hold a perfectly valid certificate, because a certificate proves control of a name, not good intentions. The padlock means the connection is private, not that the other end is trustworthy. That distinction is one of the most important in applied security.
The handshake in TLS 1.3
TLS 1.3 streamlined the handshake to one round trip:
- The client sends a ClientHello: supported versions, cipher suites, a Diffie-Hellman key share, and the hostname it wants in the SNI extension.
- The server replies with a ServerHello, its own key share, and its certificate, all in one trip.
- Both sides run Diffie-Hellman on the key shares to derive the same session keys. An observer who saw every byte cannot compute them.
- The client verifies the certificate chain, and encrypted application data starts flowing.
Because SNI travels before encryption is established, an on-path observer can usually see which site you are reaching even though not what you do there. Encrypted ClientHello (ECH) is closing that gap.
What a cipher suite is, and forward secrecy
The negotiated cipher suite names the algorithms for the connection: the key exchange (ECDHE), the bulk cipher and mode (AES-256-GCM or ChaCha20-Poly1305, both authenticated encryption), and the hash. TLS 1.3 removed every option that was not authenticated encryption, which eliminated a whole generation of mistakes.
The key exchange being ephemeral (the E in ECDHE) gives forward secrecy: the Diffie-Hellman secrets are generated per connection and thrown away, so stealing the server’s long-term private key tomorrow does not decrypt traffic recorded today. This is why “harvest now, decrypt later” is a concern for the key-exchange algorithm specifically, and why post-quantum key exchange is being deployed first.
Session resumption and the 0-RTT tradeoff
To avoid a full handshake on every reconnect, TLS 1.3 can resume a prior session, and it offers 0-RTT, where the client sends application data in its very first message using a pre-shared key. That is fast, but 0-RTT data is replayable: an attacker who captures it can resend it, and the server has no handshake freshness to reject the duplicate. The rule is to allow 0-RTT only for safe, idempotent requests (a GET with no side effects), never for anything that changes state. It is a clean example of a performance feature creating a security obligation.
Certificates and the chain of trust
A certificate binds a public key to a name, signed by a certificate authority. Your browser trusts a set of root CAs, and server certificates chain up to them:
Root CA (trusted by your OS or browser)
└── Intermediate CA
└── shop.example.com (the server's certificate)
The browser checks that the chain leads to a trusted root, the name matches the host requested (via the Subject Alternative Name extension, not the old Common Name), the dates are valid, and the certificate is not revoked. Revocation is checked through OCSP or CRLs; OCSP stapling lets the server attach a fresh signed revocation status to the handshake so the browser need not make a separate, privacy-leaking call to the CA.
Inspect any site’s chain:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
Or decode a certificate’s full contents with the certificate decoder.
Certificate transparency
Every publicly trusted certificate is recorded in public certificate transparency logs, which keeps CAs honest (a misissued certificate is visible) and is a goldmine for recon: searching crt.sh for %.example.com lists subdomains an organization has ever obtained certificates for. Defenders should monitor these logs for certificates they did not request, which is an early warning of impersonation.
Downgrade attacks and HSTS
A network attacker’s classic move is to force a weaker protocol: strip HTTPS to HTTP (sslstrip), or trick the parties into an obsolete version or cipher (FREAK, Logjam, POODLE all exploited downgrade paths). HSTS (Strict-Transport-Security) tells the browser to only ever use HTTPS for a domain, which defeats the strip on every visit after the first. Adding the domain to the HSTS preload list closes even the first-visit gap by baking the rule into the browser.
What to check in an assessment
| Check | Good | Bad |
|---|---|---|
| Protocol versions | TLS 1.2 and 1.3 only | SSLv3, TLS 1.0, or 1.1 enabled |
| HSTS | Present, long max-age, ideally preloaded |
Missing, so first visits can be downgraded |
| HTTP behavior | Port 80 redirects straight to HTTPS | Content served over plain HTTP |
| Certificate | Valid, correct SAN, modern key | Expired, mismatched, or self-signed on a public site |
| 0-RTT | Off, or limited to idempotent requests | Enabled for state-changing requests |
| CAA records | Limit which CAs may issue | Any CA can issue for the domain |
testssl.sh and sslyze check all of this from the command line, and Qualys SSL Labs gives a free web scan for public sites you are responsible for.
Field notes: fingerprinting and attacking TLS
One command tells you everything about a host’s TLS posture:
testssl.sh https://example.com # or: sslyze --regular example.com
It enumerates protocol versions, cipher suites, certificate details, and known vulnerabilities by name. What you are hunting for:
- Legacy protocols and ciphers.
SSLv3,TLS 1.0/1.1, RC4, 3DES, or export-grade suites are findings on sight, and each has a named downgrade attack behind it (POODLE, BEAST, SWEET32, FREAK, Logjam). - Missing or weak HSTS. Without
Strict-Transport-Security, the first plaintext visit is interceptable (sslstrip downgrades the user to HTTP before the redirect to HTTPS happens). Not being on the HSTS preload list leaves that first-visit window open. - Certificate problems. Expired, self-signed, wrong-host, or wildcard-everywhere certs; a weak signature (SHA-1); or a key reused across many hosts.
Field notes: certificates as recon and the interception setup
- CT logs via the cert. Every certificate is public in Certificate Transparency, so
crt.shturns one domain into a subdomain list (see DNS). The SAN field of a single cert often names a dozen internal hosts. - SNI and virtual-host confusion. One IP serves many sites by SNI; requesting the right
Host/SNI can reach an internal or default vhost the routing did not expect. - Intercepting app traffic. To read HTTPS from a mobile or desktop app you own, run mitmproxy or Burp, install its CA on the test device, and proxy the app. When the app pins its certificate, hook the check at runtime with Frida or objection to bypass the pin. This is how you audit what an app actually sends.
All interception and scanning is for hosts and apps you own or are explicitly authorized to test.
Takeaway
TLS protects the pipe, not the endpoints. Confirm it is configured well, then remember that everything interesting still happens inside the encrypted connection, in the application.