SSL Certificate Complete Guide

Contents

What is SSL/TLS?

SSL (Secure Sockets Layer) and its successor TLS (Transport Layer Security) are cryptographic protocols that secure communication over the internet. When you visit an HTTPS site, TLS encrypts the connection between your browser and the server, preventing eavesdropping and tampering.

How it works

The TLS handshake establishes a secure connection in these steps:

  1. Client hello โ€” browser sends supported TLS versions and cipher suites
  2. Server hello โ€” server selects a version/cipher and sends its certificate
  3. Certificate verification โ€” browser validates the cert (issuer, expiry, domain match)
  4. Key exchange โ€” both sides derive a shared session key
  5. Encrypted communication โ€” all subsequent traffic is encrypted

Certificate chain

Root CA
  โ””โ”€ Intermediate CA
      โ””โ”€ End-entity certificate (your site)

Browsers trust a built-in list of root CAs. They validate your cert by walking up the chain to a trusted root.

Certificate types

By validation level

DV โ€” Domain Validation

Verifies domain ownership only. Issued in minutes. Free via Let's Encrypt. Suitable for most websites.

OV โ€” Organization Validation

Verifies domain ownership plus organization identity. Takes 1โ€“3 business days. Suitable for business sites.

EV โ€” Extended Validation

Strictest verification โ€” legal entity checks, phone verification. Takes 1โ€“2 weeks. Used by banks and large e-commerce. Note: since 2019, major browsers no longer display the green organization name bar.

By coverage

How to check a certificate

Browser

Click the padlock icon in the address bar โ†’ view certificate details: issued to, issuer, expiry date.

Command line

# View certificate info
openssl s_client -connect example.com:443 -servername example.com

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

Online tools

Common errors

Certificate expired โ€” NET::ERR_CERT_DATE_INVALID

Renew the certificate. Use Certbot's auto-renewal to prevent this.

Domain mismatch โ€” NET::ERR_CERT_COMMON_NAME_INVALID

The cert doesn't cover the domain being accessed. Get a cert for the correct domain, or use a wildcard cert.

Incomplete chain โ€” NET::ERR_CERT_AUTHORITY_INVALID

The intermediate certificate is missing from the server config.

# Nginx โ€” use fullchain.pem, not just cert.pem
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;

Mixed content

An HTTPS page loading HTTP resources (images, scripts, stylesheets). Update all resource URLs to HTTPS or use protocol-relative URLs (//example.com/image.jpg).

Let's Encrypt

Let's Encrypt is a free, automated, open CA run by the non-profit ISRG. It has made HTTPS accessible to everyone.

Certbot (recommended)

# Install on Ubuntu/Debian
sudo apt install certbot python3-certbot-nginx

# Issue and auto-configure Nginx
sudo certbot --nginx -d example.com -d www.example.com

# Test auto-renewal
sudo certbot renew --dry-run

# Cron for auto-renewal
0 0,12 * * * certbot renew --quiet

acme.sh (lightweight alternative)

curl https://get.acme.sh | sh
acme.sh --issue -d example.com -d www.example.com --nginx

Best practices

# Nginx โ€” strong TLS config
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

# Enable HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;