env.dev

HTTPS and TLS Explained: Certificates, Handshake & HSTS

Understand HTTPS, TLS certificates, the TLS handshake, cipher suites, Let's Encrypt, and HSTS for secure web communication.

Last updated:

HTTPS is HTTP over TLS — every byte between client and server is encrypted, authenticated, and integrity-checked. TLS (Transport Layer Security) replaced SSL 3.0 in 1999, yet the term "SSL" persists colloquially. As of 2024, over 95% of web traffic is encrypted via HTTPS according to Google's Transparency Report. TLS 1.3 (RFC 8446), finalized in 2018, reduced the handshake from 2 round-trips to 1 and removed all legacy cipher suites, making connections both faster and more secure.

What Is the Difference Between TLS and SSL?

SSL (Secure Sockets Layer) was developed by Netscape in the 1990s. SSL 3.0 was the last SSL version before it was superseded by TLS 1.0 in 1999. SSL 2.0 and 3.0 have known vulnerabilities (POODLE, DROWN) and are prohibited by RFC 7568. In practice, when someone says "SSL certificate" they mean a TLS certificate. Modern servers should support only TLS 1.2 and TLS 1.3.

ProtocolYearStatus
SSL 2.01995Prohibited (insecure)
SSL 3.01996Prohibited (POODLE attack)
TLS 1.01999Deprecated (2020)
TLS 1.12006Deprecated (2020)
TLS 1.22008Supported — widely used
TLS 1.32018Recommended — current standard

How Does the TLS Handshake Work?

The TLS handshake establishes a secure connection before any application data is exchanged. TLS 1.3 simplified this to a single round-trip (1-RTT), and supports 0-RTT resumption for repeat connections.

TLS 1.3 handshake (1-RTT)
Client                                    Server
  │                                          │
  │  ClientHello                             │
  │  + supported cipher suites               │
  │  + key_share (ECDHE public key)          │
  │  + supported_versions: TLS 1.3           │
  │ ──────────────────────────────────────►   │
  │                                          │
  │  ServerHello                             │
  │  + selected cipher suite                 │
  │  + key_share (server ECDHE public key)   │
  │  {EncryptedExtensions}                   │
  │  {Certificate}                           │
  │  {CertificateVerify}                     │
  │  {Finished}                              │
  │  ◄──────────────────────────────────────  │
  │                                          │
  │  {Finished}                              │
  │ ──────────────────────────────────────►   │
  │                                          │
  │  ═══ Application Data (encrypted) ═══   │

After key exchange, both sides derive symmetric session keys using HKDF. All application data is encrypted with AEAD ciphers (AES-128-GCM, AES-256-GCM, or ChaCha20-Poly1305 in TLS 1.3).

What Are TLS Certificate Types?

Certificates are issued by Certificate Authorities (CAs) and come in three validation levels. The encryption strength is identical across all types — the difference is how thoroughly the CA verifies the applicant's identity.

TypeValidationIssuance timeUse case
DV (Domain Validation)Domain ownership onlyMinutesBlogs, APIs, most websites
OV (Organization Validation)Domain + organization checkDaysBusiness websites
EV (Extended Validation)Domain + legal entity auditWeeksBanks, government portals
Wildcard (*.example.com)Domain (any subdomain)Minutes–DaysMulti-subdomain setups
SAN / Multi-domainMultiple specific domainsMinutes–DaysShared hosting, CDNs

How Does Let's Encrypt Work?

Let's Encrypt is a free, automated CA that issues DV certificates using the ACME (Automatic Certificate Management Environment) protocol. It has issued over 4 billion certificates since launching in 2015. Certificates are valid for 90 days, encouraging automation.

Certbot (Let's Encrypt client)
# Install certbot
sudo apt install certbot python3-certbot-nginx

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

# Obtain certificate only (manual installation)
sudo certbot certonly --standalone -d example.com

# Auto-renewal (usually set up by default)
sudo certbot renew --dry-run

# Certificate files location
# /etc/letsencrypt/live/example.com/fullchain.pem  (cert + intermediates)
# /etc/letsencrypt/live/example.com/privkey.pem    (private key)

What Is HSTS and Why Does It Matter?

HTTP Strict Transport Security (HSTS) tells browsers to only connect via HTTPS, even if the user types http://. This prevents SSL-stripping attacks where a man-in-the-middle downgrades the connection to plain HTTP.

HSTS header
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

The preload directive lets you submit your domain to browser HSTS preload lists (hstspreload.org), hardcoding HTTPS enforcement before the first visit. Once preloaded, removal takes months — only enable this when you are certain all subdomains support HTTPS.

What Is Certificate Pinning?

Certificate pinning binds a host to a specific certificate or public key, rejecting connections even if a valid CA-signed certificate is presented by a different key. This defends against compromised CAs. However, HTTP Public Key Pinning (HPKP) was deprecated in 2018 because misconfiguration caused permanent site lockouts. Modern alternatives include Certificate Transparency (CT) logs and CAA DNS records.

CAA DNS record (limits which CAs can issue)
# Only Let's Encrypt and Cloudflare can issue certificates for this domain
example.com.  CAA  0 issue "letsencrypt.org"
example.com.  CAA  0 issue "digicert.com"
example.com.  CAA  0 iodef "mailto:security@example.com"

What Are Cipher Suites?

A cipher suite is a combination of algorithms used for key exchange, authentication, bulk encryption, and message authentication. TLS 1.3 drastically simplified the options to five secure suites.

TLS 1.3 cipher suites
TLS_AES_128_GCM_SHA256         # Most common, excellent performance
TLS_AES_256_GCM_SHA384         # 256-bit key, higher security margin
TLS_CHACHA20_POLY1305_SHA256   # Faster on devices without AES-NI
TLS_AES_128_CCM_SHA256         # Constrained IoT environments
TLS_AES_128_CCM_8_SHA256       # Minimal overhead IoT variant
Recommended Nginx TLS configuration
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

Key Takeaways

  • • TLS replaced SSL decades ago — disable SSL 3.0 and TLS 1.0/1.1 on all servers
  • • TLS 1.3 is the current standard: 1-RTT handshake, no legacy ciphers, forward secrecy by default
  • • Use Let's Encrypt with automated renewal for DV certificates
  • • Enable HSTS to prevent downgrade attacks; consider preloading for critical domains
  • • Use CAA records instead of certificate pinning to restrict which CAs can issue for your domain
  • • Test your TLS configuration at ssllabs.com/ssltest — aim for an A+ rating

Frequently Asked Questions

What is the difference between SSL and TLS?

TLS (Transport Layer Security) is the modern successor to SSL (Secure Sockets Layer). SSL is deprecated and insecure. When people say "SSL", they usually mean TLS. Use TLS 1.2 or 1.3 — disable everything older.

How does the TLS handshake work?

The client sends supported cipher suites, the server responds with a certificate and chosen cipher, the client verifies the certificate, both sides derive session keys using asymmetric crypto, then switch to fast symmetric encryption.

What is HSTS?

HTTP Strict Transport Security tells browsers to always use HTTPS for your domain. Set the Strict-Transport-Security header with a max-age value. This prevents SSL stripping attacks and accidental HTTP connections.

Was this helpful?

Stay up to date

Get notified about new guides, tools, and cheatsheets.