Search Tech Journey

Find topics, journeys and posts

6-month learning plan82 / 130
back to blog
systemsintermediate 15m read

S082 · TLS 1.3, PKI & Cert Lifecycle

The green padlock, demystified.

Module M10: Security · Session 82 of 130 · Track: SYS 🔐

What you'll be able to do after this session

  • Explain TLS 1.3, PKI & Cert Lifecycle to a friend in one minute, out loud, no notes.
  • Recognise it when you see it in real code / systems / papers.
  • Complete the hands-on exercise at the end without looking up help.

Prerequisites

If you can't answer these in 30 seconds each, redo the linked session first:


Pre-read (skim before the session)


(a) Intuition · 5 min

The one-paragraph mental model. Why this concept exists, what problem it solves, and the analogy that makes it stick.

In one sentence: The green padlock, demystified.

TLS is what puts the "S" in HTTPS. The problem it solves is old-fashioned: I'm sending my credit card number over dozens of routers I don't control. Anyone in the middle can (a) read it, (b) modify it, or (c) pretend to be the bank. TLS gives us three properties in one bundle — confidentiality (encrypted), integrity (tamper-evident), and authentication (you're really talking to bank.com, not a coffee-shop wifi router).

The magic trick is that we don't need to have met the bank in person to trust them. Instead, we trust a small set of Certificate Authorities (CAs) — DigiCert, Let's Encrypt, GoDaddy, etc. — that your OS and browser ship with. The CA has previously verified that "the person controlling bank.com owns this public key". When your browser connects, the bank presents a certificate signed by the CA. Your browser checks the CA signature, and transitively trusts the bank. That whole chain-of-trust setup is called PKI — Public Key Infrastructure.

TLS 1.3 (the current version, 2018+) reduced the handshake to a single round-trip and threw out every crypto algorithm that had ever been broken (RC4, MD5, SHA-1, CBC modes, RSA key exchange). If you see TLS 1.0 or 1.1 anywhere in 2026, that's a bug.

Certificates have a lifecycle: issue → deploy → monitor expiry → renew → revoke if compromised. Every ops team has been paged at 3 AM because a cert expired and took the site down. Automation (certbot, cert-manager, ACM) is the fix.

Gotcha to carry forever: TLS proves you're talking to the domain on the cert. It does not prove the person behind the domain is honest. hackerbank.com can have a perfectly valid green padlock.


(b) Visual walkthrough · 15 min

Diagrams, worked examples, step-by-step visuals.

Here's the TLS 1.3 handshake — one round trip, and you're encrypted:

Worked example — the chain of trust. When you visit https://github.com:

LevelCertificateSigned byTrusted because
Leafgithub.comSectigo ECC Domain Validationits issuer is intermediate
IntermediateSectigo ECC DV CAUSERTrust ECC Cert Authits issuer is a root
RootUSERTrust ECC Cert Authselfhard-coded in your browser

Your browser walks the chain from leaf to root. If the root is in the trust store, you're good.

Worked example 2 — why certs expire. A cert is a statement: "as of Jan 1, this key belongs to bank.com". If the private key later leaks and the CA never hears about it, the statement is a lie. Short expiries (Let's Encrypt: 90 days) bound the damage. There's a live proposal to move all public certs to 47 days by 2029 — automated renewal is now table stakes.

Common cert fields to know:

  • CN / Subject Alt Name (SAN): the domain(s) the cert is valid for. Modern certs use SAN only.
  • NotBefore / NotAfter: validity window.
  • Extended Key Usage: what it's for (serverAuth, clientAuth, codeSigning).
  • CRL / OCSP: revocation-check pointers.

(c) Hands-on · 20 min

Code you type and run. Not pseudo-code — real, runnable, copy-pasteable.

Two terminal exercises. First inspect a real cert; then issue one yourself locally with a mini-CA.

# ---------- 1. Inspect any live site's cert ----------
DOMAIN=github.com
echo | openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} 2>/dev/null   | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
 
# TLS version + cipher actually negotiated
echo | openssl s_client -connect ${DOMAIN}:443 -tls1_3 2>/dev/null   | grep -E "Protocol|Cipher"
 
# ---------- 2. Build a tiny local PKI ----------
mkdir -p /tmp/mypki && cd /tmp/mypki
 
# (a) Create a Root CA
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650   -subj "/CN=My Toy Root CA" -out rootCA.crt
 
# (b) Create a server key + CSR
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=localhost" -out server.csr
 
# (c) Sign the CSR with our Root CA (adds SAN for localhost)
cat > san.ext <<EOF
subjectAltName=DNS:localhost,IP:127.0.0.1
EOF
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial   -out server.crt -days 30 -sha256 -extfile san.ext
 
# (d) Run an HTTPS server with the new cert
python3 -c "
import http.server, ssl
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain('server.crt', 'server.key')
srv = http.server.HTTPServer(('127.0.0.1', 8443), http.server.SimpleHTTPRequestHandler)
srv.socket = ctx.wrap_socket(srv.socket, server_side=True)
print('serving on https://127.0.0.1:8443')
srv.serve_forever()
" &
SERVER_PID=$!
sleep 1
 
# (e) Curl it — will FAIL until you tell curl about your CA
curl -sv https://127.0.0.1:8443/ 2>&1 | head -5 || true      # SSL cert problem
curl -sv --cacert rootCA.crt https://127.0.0.1:8443/ 2>&1 | grep "SSL connection"
 
kill $SERVER_PID

Observe when you run it:

  1. Real GitHub cert shows Sectigo/USERTrust issuer chain and ~90-day validity window.
  2. Your negotiated protocol is TLSv1.3 and cipher likely TLS_AES_128_GCM_SHA256.
  3. The self-signed curl fails first — proving that browsers don't trust arbitrary certs.
  4. With --cacert, curl now trusts your toy CA and completes the handshake.
  5. The server.crt is valid only for localhost/127.0.0.1 (see SAN).

Try this modification: delete the SAN extension file and re-sign. Now curl (even with --cacert) fails with "certificate subject name does not match". That's the SAN rule biting you.


(d) Production reality · 10 min

How this shows up in real systems, gotchas, war stories, common bugs.

The Heartbleed bug (2014, CVE-2014-0160). OpenSSL let an attacker read 64 KB of server memory per malformed heartbeat request. Everyone on the internet had to rotate every private key. The lesson: even the crypto library itself is code, and code has bugs. This is why modern deployments favour battle-tested libraries (BoringSSL, LibreSSL, rustls) and why memory-safe languages for TLS stacks matter.

The 2018 Symantec distrust. Google and Mozilla removed trust in all Symantec-issued certs after finding misissuances. Millions of sites had to rotate. Lesson: your CA is a dependency, and dependencies can go bad.

Expired-cert outages that made the news: Microsoft Teams (Feb 2020), Cisco WebEx (2020), LinkedIn (2021), Ericsson (2018 — took down 32 M UK mobile users). The fix everyone converged on: automate renewal with certbot / cert-manager / ACM, monitor NotAfter with alerts 30/14/7 days out.

mTLS (mutual TLS). In microservices, you want both sides to prove identity — not just the server. Service meshes (Istio, Linkerd) auto-issue short-lived (~24h) certs to every pod and rotate them silently. This replaces Authorization: Bearer for internal traffic.

SNI leak. Even with TLS 1.3, the domain you're visiting is sent in plaintext in the ClientHello (SNI field). ECH (Encrypted Client Hello) fixes this — rolling out now on Cloudflare + Firefox.

How Cloudflare / Fastly handle it at scale. They terminate TLS at their edge (millions of certs stored on every POP), then re-encrypt to origin. This gives DDoS protection but means Cloudflare technically sees your plaintext — hence "Full (Strict)" mode where the origin also has a cert.

Rules teams live by: disable TLS 1.0/1.1, enable HSTS with preload, prefer ECDSA over RSA for speed, monitor Certificate Transparency logs (crt.sh) for rogue certs issued in your name, and never, ever put a private key in a git repo.


(e) Quiz + exercise · 10 min

  1. What three security properties does TLS provide, and which one does the certificate specifically deliver?
  2. How does TLS 1.3's handshake differ from TLS 1.2 in terms of round trips?
  3. What is a Certificate Authority and why do we trust root CAs at all?
  4. Give two reasons short-lived certificates (e.g., 90-day Let's Encrypt) are safer than 2-year certificates.
  5. Explain SNI and why it's a privacy leak even under TLS 1.3.

Stretch (connects to S081 — AuthN): mTLS uses client certificates instead of passwords for service-to-service AuthN. Sketch how a Kubernetes service mesh could issue per-pod certificates every 24 hours without any human intervention, and compare the revocation story vs a bcrypt-password system.


Explain-out-loud test

If you can't teach these 3 things to a friend without notes, redo the session:

  1. What is TLS 1.3, PKI & Cert Lifecycle? (one sentence, no jargon)
  2. When would you use it? (one concrete example)
  3. When would you NOT use it? (one anti-pattern)

What comes next


Part of a 130-session evergreen learning series. Session structure: (a) intuition · (b) visual walkthrough · (c) hands-on · (d) production reality · (e) quiz + exercise. Duration: 60 minutes.

More from M10 · Security

all modules →
  1. 081AuthN vs AuthZ, Sessions & Password Storage
  2. 083OWASP Top 10, Secrets Mgmt & Threat Modelling