Network Security
TLS and HTTPS
The application writes plaintext and reads
JrCodex·9 min read
Jr Codex Computer Networks Notes
Level: Advanced Prerequisites: Chapter 2: Cryptography for Networks Time to complete: ~25 minutes
Table of Contents
- Where TLS Sits
- The TLS 1.3 Handshake
- Certificates
- The Certificate Authority Model
- Validating a Certificate
- What TLS Does Not Protect
- Summary & Next Steps
1. Where TLS Sits
The Position
─────────────────────────────────────────
APPLICATION HTTP, SMTP, IMAP...
▲
│ plaintext
▼
TLS encrypt, authenticate, verify
▲
│ ciphertext
▼
TRANSPORT TCP
▲
▼
NETWORK IP
The application writes plaintext and reads
plaintext. TLS transforms it in between.
This is why HTTPS is just HTTP over TLS — not a
different protocol. Everything in Module 5,
Chapter 2 applies unchanged.
─────────────────────────────────────────
What It Provides
─────────────────────────────────────────
CONFIDENTIALITY AEAD symmetric encryption
(Chapter 2)
INTEGRITY built into AEAD
AUTHENTICATION certificates — usually the
SERVER only, optionally both
FORWARD SECRECY mandatory ECDHE in TLS 1.3
It is the hybrid model from Chapter 2: asymmetric
crypto to authenticate and agree a key, symmetric
crypto for the data.
─────────────────────────────────────────
2. The TLS 1.3 Handshake
One Round Trip
─────────────────────────────────────────
CLIENT SERVER
│ │
│── ClientHello ────────────────────►│
│ supported versions │
│ cipher suites │
│ KEY SHARE (a DH public value) │
│ SNI: example.com │
│ │
│◄─ ServerHello ─────────────────────│
│ chosen cipher │
│ KEY SHARE (server's DH value) │
│ ── both sides can now derive the │
│ shared secret ── │
│ ┌ ENCRYPTED FROM HERE ──────────┐│
│ │ Certificate ││
│ │ CertificateVerify (a signature││
│ │ proving key possession) ││
│ │ Finished ││
│ └───────────────────────────────┘│
│ │
│── Finished ───────────────────────►│
│── Application data ───────────────►│
─────────────────────────────────────────
Why TLS 1.3 Is One Round Trip
─────────────────────────────────────────
TLS 1.2 took TWO: negotiate the cipher, THEN
exchange keys.
TLS 1.3 removed the negotiation. It supports only
a handful of modern AEAD ciphers and mandatory
ECDHE, so the client can GUESS the parameters and
send its key share immediately.
Removing choices removed a round trip — and also
removed every downgrade attack that exploited
negotiating weak options.
─────────────────────────────────────────
CertificateVerify Is the Crucial Message
─────────────────────────────────────────
A certificate is public. Anyone can copy one.
So presenting a certificate proves nothing.
CertificateVerify is a SIGNATURE over the
handshake so far, made with the certificate's
PRIVATE key. It proves the server actually HOLDS
the key the certificate names.
Without it, an attacker could replay any
certificate they had seen. This message is what
makes the whole model work.
─────────────────────────────────────────
SNI — Server Name Indication
─────────────────────────────────────────
The client names the host it wants IN THE
CLIENTHELLO, before encryption begins.
WHY: the server must choose which certificate to
present, and it hosts many sites on one IP
(Module 5, Chapter 2's virtual hosting problem,
one layer down).
CONSEQUENCE: SNI is sent in PLAINTEXT. An
observer learns which site you are visiting, even
though the content is encrypted.
ECH (Encrypted Client Hello) fixes this and is
still being deployed.
─────────────────────────────────────────
3. Certificates
What an X.509 Certificate Contains
─────────────────────────────────────────
SUBJECT who this identifies
(the domain)
SUBJECT ALT NAMES the domains it is valid for
── the field ACTUALLY used;
Common Name is legacy
PUBLIC KEY the subject's public key
ISSUER which CA signed it
VALIDITY not-before and not-after
dates
SIGNATURE the CA's signature over all
of the above
EXTENSIONS key usage, CRL and OCSP
locations, SCTs
─────────────────────────────────────────
The One-Sentence Definition
─────────────────────────────────────────
A certificate is a SIGNED STATEMENT that a
particular PUBLIC KEY belongs to a particular
NAME.
It is Chapter 2's digital signature, applied to
the problem of knowing whose key you have.
─────────────────────────────────────────
# Inspect a live certificate.
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
# Check what the handshake actually negotiated.
openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>&1 | grep -E "Protocol|Cipher"Validation Levels
─────────────────────────────────────────
DV Domain Validated — proves control of the
domain. Automated, free (Let's Encrypt).
OV Organisation Validated — the CA checked the
organisation exists.
EV Extended Validation — more checks.
BROWSERS NO LONGER DISTINGUISH THEM VISUALLY. The
EV green bar was removed because studies showed
users did not notice or understand it.
All three provide identical CRYPTOGRAPHIC
protection. DV is sufficient for almost
everything, and its automation is why HTTPS
adoption went from a minority to near-universal.
─────────────────────────────────────────
4. The Certificate Authority Model
The Chain of Trust
─────────────────────────────────────────
ROOT CA
Self-signed. Its public key is SHIPPED WITH
your operating system and browser. This is the
trust anchor — you trust it because your vendor
put it there.
│ signs
▼
INTERMEDIATE CA
Used for day-to-day issuance, so the root's
private key can stay offline in a vault.
│ signs
▼
LEAF CERTIFICATE
example.com's certificate.
Verification walks UP the chain: each signature
is checked with the issuer's public key, until a
trusted root is reached.
─────────────────────────────────────────
THE MODEL'S WEAKNESS
─────────────────────────────────────────
ANY trusted CA can issue a certificate for ANY
domain.
Your browser trusts 100+ root CAs from many
jurisdictions. A single compromised or coerced CA
can issue a valid certificate for your bank.
This has happened. DigiNotar was compromised in
2011 and used to issue certificates for Google
domains, enabling large-scale interception. The
CA was removed from trust stores and went
bankrupt.
The trust model is only as strong as its WEAKEST
CA — and you cannot choose which ones your
browser trusts.
─────────────────────────────────────────
The Mitigations
─────────────────────────────────────────
CERTIFICATE TRANSPARENCY
All issued certificates are logged to public
append-only logs. Chrome REQUIRES SCTs proving
a certificate is logged.
Domain owners can therefore DETECT
unauthorised issuance for their names — which
is how misissuance is now caught.
CAA RECORDS
A DNS record naming which CAs may issue for
your domain (Module 5, Chapter 1).
CAs are required to check it.
CERTIFICATE PINNING
An application hard-codes the expected
certificate or key. Strong, and risky — a
rotation mistake bricks your app. Largely
abandoned for browsers, still used in mobile
apps.
─────────────────────────────────────────
5. Validating a Certificate
What a Correct Client Checks
─────────────────────────────────────────
1. SIGNATURE CHAIN valid up to a trusted root
2. NOT EXPIRED and not yet valid — check dates
3. HOSTNAME MATCHES a Subject Alternative Name
4. NOT REVOKED — OCSP or CRL
5. KEY USAGE permits server authentication
6. SIGNATURE ALGORITHM is not deprecated
7. CertificateVerify proves key possession
(Section 2)
Skip ANY of these and the guarantee collapses.
Step 3 is the one most often omitted in custom
code — and without it, ANY valid certificate for
ANY domain is accepted.
─────────────────────────────────────────
import ssl, socket
def secure_connect(host, port=443):
ctx = ssl.create_default_context() # verification ON, hostname checking ON
# ctx.check_hostname = False # ← NEVER. This removes step 3.
# ctx.verify_mode = ssl.CERT_NONE # ← NEVER. This removes steps 1, 2, 4.
with socket.create_connection((host, port), timeout=5) as sock:
with ctx.wrap_socket(sock, server_hostname=host) as tls: # server_hostname = SNI
print(f"protocol: {tls.version()}")
print(f"cipher: {tls.cipher()[0]}")
cert = tls.getpeercert()
print(f"subject: {dict(x[0] for x in cert['subject'])}")
print(f"expires: {cert['notAfter']}")
return tls.version()
secure_connect("example.com")THE MOST DANGEROUS TWO LINES IN NETWORKING
─────────────────────────────────────────
verify=False
check_hostname = False
They appear constantly in tutorials and Stack
Overflow answers as a fix for certificate
errors.
They convert an authenticated encrypted channel
into an encrypted channel to WHOEVER ANSWERED —
which is precisely the machine-in-the-middle you
were defending against (Chapter 1).
The connection still shows as TLS. Nothing looks
wrong. The protection is simply gone.
IF A CERTIFICATE FAILS TO VALIDATE, FIX THE
CERTIFICATE. For internal services, add your
internal CA to the trust store — do not disable
verification.
─────────────────────────────────────────
6. What TLS Does Not Protect
The Limits
─────────────────────────────────────────
METADATA
Which host you connected to (SNI, Section 2),
when, how much data, for how long. Traffic
analysis works fine against TLS.
THE ENDPOINTS
TLS protects data IN TRANSIT. A compromised
server, a malicious browser extension, or
malware on your machine sees plaintext.
THE SERVER'S BEHAVIOUR
TLS proves you are talking to example.com. It
says NOTHING about whether example.com is
trustworthy. A phishing site with a valid
certificate is properly encrypted, and still a
phishing site.
DNS
Your lookup happened before TLS existed on the
connection. Use DoH or DoT (Module 5,
Chapter 1).
IMPLEMENTATION FLAWS
Heartbleed was a bug in OpenSSL, not in TLS.
The protocol being sound does not make every
implementation sound.
─────────────────────────────────────────
The Padlock Misconception
─────────────────────────────────────────
"The padlock means the site is safe."
It means the CONNECTION is encrypted and the
server proved control of that domain name.
It says nothing about the site's honesty, its
security practices, or what it does with your
data. Most phishing sites use HTTPS — free
certificates made that trivial.
Encrypted ≠ trustworthy. That distinction is the
single most useful thing to understand about
HTTPS.
─────────────────────────────────────────
Practical Configuration
─────────────────────────────────────────
□ TLS 1.2 and 1.3 only; disable everything older
□ Strong cipher suites only; no RC4, no 3DES,
no export ciphers
□ HSTS: Strict-Transport-Security, so browsers
refuse plaintext to your domain
□ Redirect all HTTP to HTTPS
□ Automate renewal — expired certificates are a
leading cause of outages
□ Publish CAA records
□ Monitor Certificate Transparency logs for your
domains
─────────────────────────────────────────
7. Summary & Next Steps
Key Takeaways
- TLS 1.3 completes its handshake in one round trip by removing negotiation — which also eliminated the downgrade attacks that negotiation enabled.
- A certificate is public and copyable, so CertificateVerify's signature proving private-key possession is what actually authenticates the server.
- Any trusted CA can issue for any domain, making the model only as strong as its weakest CA; Certificate Transparency exists to detect misissuance rather than prevent it.
- Disabling certificate verification leaves an encrypted channel to whoever answered, which is exactly the attack encryption was meant to prevent.
Concept Check
- Why is presenting a valid certificate insufficient to authenticate a server?
- Why must SNI be sent in plaintext, and what does that leak?
- A phishing site shows a valid padlock. Explain precisely what the padlock does and does not assert.
Next Chapter
→ Chapter 4: Firewalls, VPNs and Defence in Depth
Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index | Back to Computer Networks Index