The trust problem

When you open your bank's website, your browser receives a public key and uses it to set up encryption. Encryption alone is not enough: if an attacker on the same Wi-Fi can hand you their public key instead, you would set up a perfectly encrypted connection — to the attacker. The real question is: how do you know that this public key belongs to your bank?

You have never met the bank's servers, so you need someone you already trust to vouch for them. A public key infrastructure (PKI) is the system that does this: the certificates, the certificate authorities that issue and sign them, the policies and procedures they follow, and the ways to check and revoke certificates. The cryptography underneath — key pairs, hashes and digital signatures — is explained in Cryptography Basics.

Digital certificates

A digital certificate is a small signed document that says, in effect: "the public key below belongs to www.example.com, from this date until that date — signed, the issuer". Because the issuer signed it, nobody can change the name or swap the key without breaking the signature. The certificate is public; the matching private key stays on the server and is never part of the certificate.

The format used almost everywhere is X.509 (version 3). The fields you will meet most:

Field What it holds Why it matters
Subject Who the certificate is for, e.g. CN=www.example.com The common name (CN) is now informational; browsers match names against the SAN
Subject Alternative Name (SAN) The list of names the certificate is valid for The name you typed must appear here, or the browser warns
Issuer The CA that signed it Tells the client which certificate to check next
Validity (Not Before / Not After) The start and end date and time Outside this window the certificate is rejected
Public key The subject's public key and its algorithm (RSA, ECDSA) The key the client uses to verify the server
Serial number A unique number per issuer Used to identify the certificate when it is revoked
Extensions Key usage, extended key usage, basic constraints, CRL and OCSP locations Limit what the key may do (e.g. server authentication only) and whether it may sign other certificates
Signature The issuer's digital signature over all of the above Proves the content was not changed since the CA signed it

Certificate authorities and the chain of trust

A certificate authority (CA) is an organization — or, inside a company, a server — that checks a requester's claim to a name and then signs a certificate for it. Public CAs are audited and must follow the Baseline Requirements of the CA/Browser Forum, a body of CAs and browser makers.

Root and intermediate CAs

CAs are arranged in a hierarchy. At the top is a root CA, whose certificate is self-signed: it vouches for itself, so it is only trusted because your device ships with it. A root key is so valuable that it is kept offline, usually in a hardware security module (HSM). The root signs one or more intermediate CAs, and the intermediates sign the server ("leaf") certificates day to day. If an intermediate is compromised, it can be revoked without replacing the root on every device in the world.

The chain of trust is the path a client follows from the server certificate up to a trusted root: each certificate is signed by the next one up, and the client checks every signature, validity period and constraint on the way. The server sends its own certificate plus the intermediates; the client supplies the root from its own trust store.

Chain of trust: a root CA in the device's trust store signs an intermediate CA, which signs the server certificate for www.example.com. The server sends its certificate and the intermediate; the client verifies the chain upward to the root. Trust store on the device Root CA self-signed, offline signs Intermediate CA issuer: Root CA signs www.example.com issuer: Intermediate sent by the server during the TLS handshake Client verifies: leaf → intermediate → trusted root
Signatures flow down the hierarchy; verification runs up it. The root is never sent by the server: the client must already have it.

Where the trusted roots come from

Each operating system and some browsers maintain a root store: the list of root certificates they trust, managed by root programs such as those of Microsoft, Apple, Google (Chrome) and Mozilla. Roots are added after audits and removed when a CA breaks the rules — browsers have distrusted CAs for misissuing certificates. Updates to the root store arrive with normal OS and browser updates, which is one more reason to patch.

Organizations can add their own roots, for example for an internal CA or for a TLS-inspecting proxy (see Network Security in Depth). Every root you add can vouch for any name, so add only what you control, and manage it centrally.

TLS: putting the certificate to work

Transport Layer Security (TLS) is the protocol that protects HTTPS, secure email transport, many VPNs and countless APIs. It replaced the older Secure Sockets Layer (SSL); people still say "SSL certificate", but every current version is TLS. TLS gives three things: the server's identity is verified (through its certificate), the data is encrypted (confidentiality) and any tampering is detected (integrity).

The handshake at a high level (TLS 1.3, simplified)

  1. Client hello. The client lists the TLS versions and cipher suites it supports, sends its share of a key exchange, and names the site it wants (Server Name Indication, SNI), so one server can host many sites.
  2. Server hello and certificate. The server picks a version and cipher suite, sends its key share, its certificate chain, and a signature made with its private key over the handshake so far. That signature proves it really holds the private key belonging to the certificate. In TLS 1.3 both sides already derive handshake keys from the key shares, so the certificate is sent encrypted.
  3. The client checks. Does the chain lead to a trusted root? Are all signatures valid and all certificates within their dates? Is the name in the SAN? Any "no" means a warning or a refused connection.
  4. Session keys. From the two key shares, both sides compute the same secret (an ephemeral Diffie–Hellman key exchange) and derive symmetric keys from it.
  5. Encrypted data. Everything afterward is encrypted with a fast symmetric cipher such as AES-GCM or ChaCha20-Poly1305.

This is the hybrid pattern described in Cryptography Basics: asymmetric cryptography for identity and key agreement, symmetric cryptography for the bulk data. Because the session keys come from ephemeral key shares that are thrown away, a recording of today's traffic cannot be decrypted later even if the server's private key leaks — this property is called forward secrecy.

TLS 1.2 and TLS 1.3

TLS 1.3 (2018) is the current version; TLS 1.2 (2008) is still widely supported and acceptable when configured with strong cipher suites. TLS 1.3 needs one round trip less to set up a connection, removed old and weak options (static RSA key exchange, CBC-mode ciphers, SHA-1 signatures), always provides forward secrecy, and encrypts the certificate itself during the handshake. SSL 2.0 and 3.0, TLS 1.0 and TLS 1.1 are deprecated and should be disabled.

What the padlock does — and does not — prove

The padlock (or, in newer browsers such as Chrome, a neutral "tune" icon) means: the connection is encrypted, and the server proved it holds the key for a certificate that a trusted CA issued for this exact name. It does not mean the site is honest, safe or belongs to the company you think of.

Certificate types

Certificates differ in how thoroughly the CA checked the requester (validation level) and in how many names they cover.

Type What it means Typical use
Domain validated (DV) The CA only checked that the requester controls the domain (a DNS record, a file on the web server) Most websites; what ACME CAs issue automatically
Organization validated (OV) The CA also checked that the organization exists Company sites that want the organization name in the certificate
Extended validation (EV) A stricter, documented check of the organization Still sold, but browsers stopped showing a special green bar around 2019, so users rarely see the difference
Wildcard *.example.com covers one level of subdomains: www.example.com and shop.example.com, but not example.com itself or a.b.example.com Many subdomains on the same servers
Multi-domain (SAN) One certificate with an explicit list of names in the SAN A few related names, e.g. example.com and www.example.com
Self-signed Signed with its own key; no CA vouches for it Labs and device setup pages; never for public services

Getting a certificate

The classic process starts on the server: generate a key pair, then create a certificate signing request (CSR) that contains the public key and the requested names, signed with the private key to prove possession. The CA validates the request and returns the signed certificate. The private key never leaves the server.

$ openssl req -new -newkey rsa:3072 -nodes -keyout shop.key -out shop.csr \
    -subj "/CN=shop.example.com" \
    -addext "subjectAltName=DNS:shop.example.com,DNS:www.shop.example.com"

-nodes (-noenc in OpenSSL 3.0 and later) leaves the key file unencrypted, which servers usually need to start unattended — so protect shop.key with strict file permissions and keep it out of version control.

ACME and Let's Encrypt

The Automatic Certificate Management Environment (ACME, RFC 8555) protocol automates the whole cycle: an ACME client on the server proves control of the domain (by serving a token over HTTP or publishing a DNS record), receives the certificate, installs it and renews it on a schedule. Let's Encrypt, a free nonprofit CA, popularized this; many other CAs and most web servers, load balancers and hosting panels now support ACME. Common clients are Certbot, acme.sh and the built-in support in servers such as Caddy.

Shorter and shorter lifetimes

Public TLS certificates used to be valid for years; the maximum fell to 398 days in 2020. In 2025 the CA/Browser Forum voted to shrink it further in steps — at the time of writing, to 200 days from March 2026, 100 days from March 2027 and 47 days from March 2029. Let's Encrypt certificates have long lasted 90 days, and it has announced plans for even shorter ones. Check the current rules before you plan, because these schedules can change.

The reasoning: a short-lived certificate limits how long a stolen key or a wrongly issued certificate can be abused, and it forces organizations to automate renewal instead of relying on a calendar reminder. The practical consequence is clear: manual renewal of public certificates is on its way out.

Revocation

Sometimes a certificate must stop being trusted before it expires: the private key leaked, the server was decommissioned, or the certificate was issued in error. Certificate revocation is the CA declaring it invalid ahead of time. Clients learn about it in a few ways:

  • Certificate revocation list (CRL): a list of revoked serial numbers, signed and published by the CA at regular intervals. Simple, but lists can grow large and are only as fresh as their last publication.
  • Online Certificate Status Protocol (OCSP): the client asks the CA's responder about one certificate and gets a signed "good", "revoked" or "unknown". It is fresher, but it tells the CA which sites you visit and fails awkwardly when the responder is down.
  • OCSP stapling: the server fetches a recent signed OCSP response itself and "staples" it to the handshake, so the client does not have to ask the CA.

In practice, browsers have moved away from live OCSP checks; at the time of writing, major browsers mostly rely on compact revocation lists that the browser vendor pushes to clients, and several CAs — including Let's Encrypt — have stopped running OCSP services in favor of CRLs. Short certificate lifetimes are partly a response to revocation being hard to do well: a certificate that expires in a few weeks matters less if a revocation is missed.

Common problems and how to read them

Certificate errors look alarming, but nearly all of them fall into a handful of causes. The browser codes below are Chrome's; other browsers use similar names.

Symptom Usual cause Fix
Expired (NET::ERR_CERT_DATE_INVALID) Renewal failed or was forgotten Renew and install; automate renewal and monitor expiry
Name mismatch (NET::ERR_CERT_COMMON_NAME_INVALID) The name typed is not in the SAN — e.g. the certificate covers www.example.com but the user opened example.com, or an internal name or IP address Reissue with every name users actually use
Incomplete chain The server sends its own certificate but not the intermediate. Browsers often repair this, by downloading the missing intermediate (AIA fetching) or from a cache, so it "works on my laptop" but fails in other browsers, apps and scripts Configure the server with the full chain file
Untrusted issuer or self-signed (NET::ERR_CERT_AUTHORITY_INVALID) A self-signed or internal-CA certificate on a device that does not trust that root — or an interception attempt Use a public CA for public services; distribute the internal root centrally for internal ones
Valid certificate reported as expired or "not yet valid" The client's clock is wrong (dead CMOS battery, no time synchronization) Fix the time; see NTP and CMOS

Inspecting a certificate with openssl

openssl s_client connects like a browser and shows the chain and the verification result. Here a user reports that the VPN portal "suddenly gives a warning":

$ openssl s_client -connect vpn.example.com:443 -servername vpn.example.com </dev/null
CONNECTED(00000003)
depth=0 CN = vpn.example.com
verify error:num=10:certificate has expired
---
Certificate chain
 0 s:CN = vpn.example.com
   i:C = NL, O = Example Trust, CN = Example Issuing CA R1
 1 s:C = NL, O = Example Trust, CN = Example Issuing CA R1
   i:C = NL, O = Example Trust, CN = Example Root CA
---
Verify return code: 10 (certificate has expired)

The chain is complete (the server sends the leaf at depth 0 and the intermediate at depth 1), but the leaf has expired. Pipe the certificate into openssl x509 to read the fields themselves:

$ openssl s_client -connect vpn.example.com:443 -servername vpn.example.com </dev/null 2>/dev/null \
    | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
subject=CN = vpn.example.com
issuer=C = NL, O = Example Trust, CN = Example Issuing CA R1
notBefore=Mar 12 00:00:00 2026 GMT
notAfter=Sep 28 23:59:59 2026 GMT
X509v3 Subject Alternative Name:
    DNS:vpn.example.com

Other verify codes you will meet:

  • 21 (unable to verify the first certificate) — the intermediate is missing: an incomplete chain.
  • 20 (unable to get local issuer certificate) — the issuer is not in the local trust store (an internal CA, or a missing intermediate).
  • 18 (self-signed certificate) — no CA behind it.

For a certificate file on disk, openssl x509 -in cert.pem -noout -checkend 2592000 reports whether it expires within the next 30 days (2,592,000 seconds), which is handy in scripts.

Internal PKI and certificate inventory

Many organizations run their own CA for things the public internet never sees: internal web applications, Wi-Fi with 802.1X and certificate-based authentication (EAP-TLS, see 802.1X), VPN clients, domain controllers, device identities in mobile device management (MDM), and machines in operational technology networks. On Windows networks this is often Active Directory Certificate Services (AD CS). The internal root is distributed to company devices through Group Policy or MDM.

The same rules apply as for public CAs, on a smaller scale:

  • Keep the root CA offline and use it only to sign intermediates; protect CA keys, ideally in an HSM.
  • Restrict who may request which kind of certificate. Overly permissive certificate templates are a known path to privilege escalation in Windows domains, so review them like any other privileged access.
  • Publish revocation information, and document every step.

Monitoring expiry

An expired certificate is one of the most common — and most avoidable — causes of outages: a payment page, a VPN or an API between two companies stops working at midnight. The fix is an inventory of every certificate (name, issuer, owner, expiry, where it is installed) and an alert well before each expiry date. Commercial certificate management tools and monitoring systems do this at scale; the logic is simple. This example uses a fixed "today" so the output never changes:

from datetime import date

today = date(2026, 10, 1)  # fixed "today" so the output never changes

inventory = [
    ("www.example.com", "Public CA", date(2027, 1, 14)),
    ("mail.example.com", "Public CA", date(2026, 10, 19)),
    ("vpn.example.com", "Public CA", date(2026, 9, 28)),
    ("intranet.corp.example", "Internal CA", date(2026, 10, 9)),
    ("scada-hmi.corp.example", "Internal CA", date(2027, 6, 30)),
]

def status(days_left):
    if days_left < 0:
        return "EXPIRED"
    if days_left <= 14:
        return "RENEW NOW"
    if days_left <= 30:
        return "renew soon"
    return "ok"

rows = []
for name, issuer, not_after in inventory:
    days_left = (not_after - today).days
    rows.append((days_left, name, issuer))

for days_left, name, issuer in sorted(rows):
    print(f"{name:<24} {issuer:<12} {days_left:>5} days  {status(days_left)}")

attention = sum(1 for days_left, _, _ in rows if days_left <= 30)
print(f"{attention} of {len(rows)} certificates need attention")
vpn.example.com          Public CA       -3 days  EXPIRED
intranet.corp.example    Internal CA      8 days  RENEW NOW
mail.example.com         Public CA       18 days  renew soon
www.example.com          Public CA      105 days  ok
scada-hmi.corp.example   Internal CA    272 days  ok
3 of 5 certificates need attention

Sorting by days left puts the urgent work at the top. In real life the expiry dates come from scanning your own endpoints or from the CA's records, and the alert goes to the team that owns each certificate — an alert that reaches nobody is no alert. Public CAs also log every certificate they issue in Certificate Transparency logs, which you can search for your own domains to find certificates you did not know about.