Certificates

Chapter 4
Certificates & the X.509 Format
What a certificate actually contains, and how to read one with openssl

Chapter 3 left one piece dangling: the server authenticates itself by signing the handshake with its long-term private key — but how does the client know that key belongs to the right server? The answer is the certificate: a signed document binding a public key to an identity (a domain name). This chapter opens one up and names every part.

What Problem a Certificate Solves

A raw public key is just a number — it carries no identity. If a server simply handed you a public key, an impostor could hand you their public key just as easily; you'd have no way to tell which one truly belongs to example.com. A certificate fixes this by binding a public key to a name and having a trusted third party (a Certificate Authority, Chapter 5) vouch for that binding with a signature.

A certificate is "a public key + an identity + a vouching signature"
Strip away the jargon and a TLS certificate is three things glued together: (1) a public key, (2) the identity it belongs to (the domain name), and (3) a signature from a Certificate Authority asserting "I verified that this key really does belong to this domain." Everything else in the X.509 format is supporting detail around those three essentials.

X.509 — The Standard Certificate Format

TLS certificates follow the X.509 standard, which defines the fields a certificate contains. Here are the ones that matter, as you'll see them in real output:

FieldWhat it holdsWhy it matters
Subjectwho the cert identifies — incl. Common Name (CN)the identity being vouched for
Subject Alternative Name (SAN)the list of domain names the cert is valid forthis is what browsers actually check today
Issuerwhich CA issued & signed this certthe next link up the trust chain (Ch. 5)
Validity (Not Before / Not After)the date range the cert is validexpired or not-yet-valid = rejected
Public Keythe server's public key + algorithm (RSA/EC)the key being bound to the identity
Signaturethe issuer's signature over all the abovemakes the cert tamper-evident
Serial / Extensionsunique ID, key-usage flags, CRL/OCSP URLsrevocation & usage constraints (Ch. 10–11)

Reading a Real Certificate

You can fetch and decode any site's certificate with openssl. The -text option prints the X.509 fields in human-readable form:

# fetch the cert and print its fields openssl s_client -connect example.com:443 -servername example.com </dev/null \ | openssl x509 -text -noout
Certificate: Data: Version: 3 (0x2) Serial Number: 0a:1b:2c: ... Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, O=DigiCert Inc, CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1 Validity Not Before: Jan 1 00:00:00 2025 GMT Not After : Apr 1 23:59:59 2025 GMT Subject: CN=example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) X509v3 extensions: X509v3 Subject Alternative Name: DNS:example.com, DNS:www.example.com

Every concept so far appears here: the Subject identity, the Public Key (the one used in Chapter 3's signature), the Issuer (the CA that vouched for it), the Validity window, and the SAN list of covered domains.

SAN, not Common Name, is what's checked today
Historically the domain lived in the Common Name (CN) inside the Subject. Modern browsers ignore CN for hostname matching and require the domain to appear in the Subject Alternative Name extension — a cert whose name is only in CN and not in SAN will be rejected as invalid. SAN also allows multiple names (and wildcards like *.example.com) in one cert, which CN couldn't. When you check "does this cert match the site I'm visiting?", you're checking the SAN list.

How the Signature Makes It Tamper-Proof

The certificate's integrity rests on the primitives from Chapter 2. The CA computes a hash of all the certificate's data fields, then signs that hash with the CA's private key. Anyone can verify it using the CA's public key:

# conceptually, certificate verification: 1. hash the cert's data fields -> digest_now 2. decrypt the signature w/ CA public key -> digest_signed_by_CA 3. compare: digest_now == digest_signed_by_CA ? valid, untampered else ? altered or forged -> reject

Because only the CA's private key can produce a signature that verifies against its public key, nobody can alter a single field (say, swap in their own public key or change the domain) without invalidating the signature. This is the same hash-then-sign pattern from Chapter 2, applied to the certificate itself — and it's why a certificate can be transmitted in the clear yet still be trustworthy.

PEM vs DER — Encodings, Not Different Certificates

Certificates come in two file encodings, which trip up beginners because they look totally different but hold the same data:

EncodingLooks likeTypical extensions
PEMBase64 text between -----BEGIN CERTIFICATE----- markers.pem .crt .cer
DERraw binary (not human-readable).der .cer

PEM is the common one on Linux servers (and what you paste into config files); DER is binary. They're interconvertible with openssl x509 -inform/-outform, and -text decodes either into the readable field listing above. Don't mistake the encoding for the content — a .pem and a .der of the same cert are the same certificate.

Validity windows are short now — and that's deliberate
Notice the example cert is valid for only ~90 days. Public TLS certificates have moved to short lifetimes (Let's Encrypt issues 90-day certs, and the industry is moving shorter still) because short windows limit the damage of an undetected key compromise and make revocation (Chapter 11) less critical. Short lifetimes are only practical because issuance is automated — which is exactly what ACME/Let's Encrypt (Chapter 9) enables.

Hands-On Exercises

Exercise 1

Fetch a real site's certificate with openssl and print it with x509 -text -noout. Locate and write down its Subject, Issuer, Validity dates, public key algorithm/size, and the Subject Alternative Name list.

📄 View solution
Exercise 2

Use targeted openssl flags to extract just specific fields: -subject, -issuer, -dates, and -ext subjectAltName. Then explain why a browser visiting www.example.com checks the SAN list rather than the Common Name.

📄 View solution
Exercise 3

Inspect a certificate in your browser's certificate viewer (click the padlock) and find the same fields. Then reason about three rejection scenarios: an expired cert, a cert whose SAN doesn't include the visited domain, and a cert with one data field altered after signing — state which check fails in each.

📄 View solution

Chapter 4 Quick Reference

  • A certificate binds a public key to an identity (domain), vouched for by a CA's signature
  • It solves the problem that a raw public key carries no identity — an impostor's key looks the same
  • X.509 is the format; key fields: Subject, SAN, Issuer, Validity, Public Key, Signature
  • SAN (Subject Alternative Name) — the domain list browsers actually check; CN is ignored for matching
  • Read one with openssl x509 -text -noout (decodes both PEM and DER)
  • The CA hashes then signs the cert data — altering any field breaks the signature (tamper-evident)
  • PEM (Base64 text) vs DER (binary) are encodings of the same certificate
  • Validity windows are short (~90 days) by design — automation (ACME) makes that practical
  • Next chapter: Certificate Authorities & the chain of trust — who signs the signers