HTTPS
06 / 07

TLS/SSL — Certificates & Handshake

TLS/SSL — Certificates & Handshake

TLS (Transport Layer Security) encrypts communication between client and server. SSL is the deprecated predecessor — when people say "SSL" they usually mean TLS. HTTPS = HTTP over TLS.

TLS Handshake (TLS 1.3)

TLS 1.3 reduced the handshake to 1 RTT (vs 2 RTT in TLS 1.2). It also supports 0-RTT resumption for repeat connections.

Client                          Server
  |                                |
  |--- ClientHello --------------->|  (supported ciphersuites, TLS version, random)
  |                                |
  |<-- ServerHello ----------------|  (chosen ciphersuite, random)
  |<-- Certificate ----------------|  (server's cert + chain)
  |<-- CertificateVerify ----------|  (signature proving server owns the cert's private key)
  |<-- Finished -------------------|  (MAC of handshake)
  |                                |
  |--- Finished ------------------>|  (client confirms)
  |                                |
  |=== Encrypted data exchange ====|

Total: 1 RTT (TLS 1.2 needed 2 RTTs)

Certificates — Chain of Trust

  • Root CA: self-signed, trusted by OS/browser (e.g., DigiCert, Let's Encrypt ISRG Root)

  • Intermediate CA: signed by Root CA, signs leaf certificates. Allows Root to stay offline.

  • Leaf certificate: your domain's certificate, signed by Intermediate CA

  • fullchain.pem (Let's Encrypt): leaf + intermediates in one file — always use this in server config

  • privkey.pem: your private key — never share, keep secure, used to prove cert ownership

Certificate Types

  • DV (Domain Validated): just proves you control the domain. Automated, instant, free (Let's Encrypt). Shows padlock icon.

  • OV (Organization Validated): CA verifies your organization exists. Shows org name in cert details.

  • EV (Extended Validation): stricter verification, green bar in older browsers. Largely obsolete — Chrome removed visual distinction.

  • Wildcard (*.example.com): covers all first-level subdomains. Cannot be issued by Let's Encrypt automatically (requires DNS challenge).

  • SAN (Subject Alternative Names): one cert covers multiple domains. Let's Encrypt supports up to 100 SANs per cert.

Let's Encrypt & Certbot

# HTTP-01 challenge (requires port 80 accessible)
sudo certbot certonly --webroot \
  --webroot-path /var/www/html \
  -d example.com -d www.example.com

# DNS-01 challenge (for wildcards, works without public server)
sudo certbot certonly --manual --preferred-challenges dns \
  -d "*.example.com" -d example.com
# Certbot prompts you to create a TXT record: _acme-challenge.example.com

# Standalone mode (certbot runs its own HTTP server on port 80)
sudo certbot certonly --standalone -d example.com

# Auto-renew test
sudo certbot renew --dry-run

# Certificate files location
ls /etc/letsencrypt/live/example.com/
# cert.pem      — leaf certificate only
# chain.pem     — intermediate chain only
# fullchain.pem — cert + chain (use in server config)
# privkey.pem   — private key

OpenSSL — Certificate Inspection

# View certificate details from file
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout

# Check live server's certificate
openssl s_client -connect example.com:443 -servername example.com

# Check expiry date
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -enddate

# Verify certificate chain
openssl verify -CAfile chain.pem cert.pem

# Generate CSR (Certificate Signing Request) for a paid cert
openssl req -new -newkey rsa:2048 -nodes \
  -keyout example.com.key \
  -out example.com.csr \
  -subj "/C=UA/ST=Kyiv/L=Kyiv/O=MyCompany/CN=example.com"

# Test TLS config
curl -I https://example.com --verbose 2>&1 | grep -E "SSL|TLS|certificate|issuer"

# Check which TLS versions are supported
nmap --script ssl-enum-ciphers -p 443 example.com

mTLS (Mutual TLS)

In mTLS, both client and server present certificates. The server verifies the client's certificate. Used for service-to-service communication, API security without passwords, and IoT device authentication.

# Generate CA, server, and client certs for mTLS
# 1. Create CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 -days 1826 -key ca.key -out ca.crt -subj "/CN=My CA"

# 2. Server cert signed by CA
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=api.example.com"
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -out server.crt

# 3. Client cert signed by CA
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/CN=my-service"
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -out client.crt

# Test mTLS connection
curl https://api.example.com \
  --cert client.crt \
  --key client.key \
  --cacert ca.crt

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free