Every HTTPS connection is protected by TLS (Transport Layer Security), the successor of SSL. People still say “SSL certificate” out of habit, but SSL itself is long obsolete. Understanding how TLS works makes certificate errors, configuration choices and debugging much less mysterious.

What TLS provides

  1. Encryption — nobody between the browser and the server can read the traffic: Wi-Fi operators, ISPs, proxies.
  2. Integrity — the data can’t be modified in transit without detection.
  3. Authentication — the browser verifies it’s really talking to example.com, not an impostor. This is what certificates are for.

Certificates and the chain of trust

A certificate binds a public key to a domain name. It’s signed by a certificate authority (CA) that browsers trust.

Root CA (built into browsers/OS trust stores)
  └── Intermediate CA (signed by the root)
        └── Your certificate: example.com (signed by the intermediate)

The browser checks the chain: your certificate was signed by the intermediate, the intermediate by a trusted root. The domain must match, and the certificate must be within its validity dates and not revoked.

Your server must send your certificate plus the intermediates (the “full chain”). Forgetting the intermediate is a classic error: it works in some browsers and fails in others and in tools like curl. See SSL certificate chain errors.

Certificate types

Type Validation Shows Use
DV (Domain Validated) Control of the domain Padlock Most websites. Let’s Encrypt issues these for free
OV (Organization Validated) Domain + company checked Padlock (details in certificate) Business sites wanting verified org info
EV (Extended Validation) Extensive company checks Padlock (browsers no longer show a green bar) Little practical benefit today

Encryption strength is identical across types. Only the identity checks differ.

Coverage: single domain, multi-domain (SAN) or wildcard (*.example.com). See wildcard certificates.

The TLS handshake (TLS 1.3, simplified)

  1. ClientHello — the browser sends supported TLS versions, cipher suites, the server name (SNI) and its key-exchange share.
  2. ServerHello — the server picks the version and cipher, sends its key share, its certificate and a signature proving it holds the private key.
  3. Both sides derive the same session keys from the key exchange (ECDHE). The private key never travels over the network.
  4. Encrypted application data flows (HTTP requests and responses).

TLS 1.3 completes this in one round trip (and can resume sessions with zero). That’s faster than TLS 1.2’s two round trips, which noticeably helps users far from the server.

Forward secrecy

With ephemeral key exchange (ECDHE), each session has unique keys. Even if your server’s private key leaks later, recorded past traffic can’t be decrypted. TLS 1.3 always uses forward secrecy.

SNI

Server Name Indication sends the hostname in the ClientHello, so one IP can serve many HTTPS sites with different certificates. That’s why you can host dozens of sites with their own certificates on one VPS. See Nginx server blocks.

TLS versions

Version Status
SSL 2.0 / 3.0 Broken. Disabled everywhere
TLS 1.0 / 1.1 Deprecated (2021). Browsers removed support
TLS 1.2 Still widely used, secure with modern ciphers
TLS 1.3 Current: faster and simpler, insecure options removed

Enable TLS 1.2 and 1.3 only. See configure TLS 1.3.

Private keys

The private key stays on the server (for example /etc/letsencrypt/live/example.com/privkey.pem), readable only by root. Anyone with the key can impersonate your site. If it leaks, revoke the certificate and issue a new one with a new key.

What HTTPS doesn’t do

  • It doesn’t make a site trustworthy. Phishing sites have valid certificates too.
  • It doesn’t protect data on the server (database, logs) or in the browser.
  • It hides content and paths, but not the fact that you’re connecting to a given IP. The domain is usually visible via SNI and DNS. Encrypted ClientHello (ECH) is starting to change that.

Working with TLS on a server

Task Guide
Free certificates for Nginx Let’s Encrypt with Certbot (Nginx)
Apache Certbot for Apache
Alternative ACME client acme.sh
Check expiry SSL expiry checks
Inspect certificates openssl commands
Enforce HTTPS HSTS

Quick inspection from the command line:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
curl -vI https://example.com 2>&1 | grep -E 'SSL connection|subject|expire'

Related: CDN for your website and HTTP status codes.

  • SSL
  • Security
  • Web