SSL, TLS, and HTTPS: Securing Web Communication
Understand TLS handshake, certificates, cipher suites, and how HTTPS works. Learn the differences between SSL and TLS and why encryption matters.
TLS protects web traffic by authenticating servers, deriving shared traffic keys, and encrypting HTTP requests and responses. This guide compares TLS 1.2 and TLS 1.3 handshakes, explains certificates, cipher suites, forward secrecy, HSTS, and mTLS, and shows how to monitor and renew HTTPS safely. It also explains why 0-RTT early data can be replayed and how to decide which requests can safely use it.
SSL, TLS, and HTTPS: Securing Web Communication
Introduction
HTTPS uses TLS to authenticate a server and protect HTTP traffic between a client and server. During the handshake, both sides agree on connection parameters and establish keys before exchanging application data.
Certificate trust, protocol versions, and renewal practices all affect whether connections stay secure and available. This guide explains the handshake, certificates, and cipher suites, then covers practical HTTPS controls such as HSTS.
graph TB
subgraph Application Layer
A[HTTP Data]
end
subgraph TLS Layer
B[TLS 1.3 Record Layer]
C[Handshake Protocol<br/>Key exchange, authentication]
D[Alert Protocol<br/>Error messages]
E[Application Data Protocol<br/>Encrypted payload]
end
subgraph Transport Layer
F[TCP]
end
subgraph Internet Layer
G[IP]
end
A --> B
B --> C
B --> D
B --> E
E --> F
F --> G
Encryption Fundamentals
SSL vs TLS
SSL (Secure Sockets Layer) came from Netscape in the mid-1990s. SSL 3.0 was the last version, released in 1996. After that, the protocol got renamed to TLS.
TLS 1.0 arrived in 1999, then 1.1 (2006), 1.2 (2008), and 1.3 (2018). TLS 1.3 cleaned house — removed obsolete features and streamlined the handshake.
When you see “SSL certificates” referenced today, you’re usually looking at TLS certificates. The old name stuck around.
Why TLS?
Without encryption, anyone on the network path can see what you send and receive. Messages, login credentials, session cookies, everything.
graph LR
A[You] -->|"Sensitive Data"| B[Open WiFi]
B -->|"Anyone can read"| C[Server]
D[Attacker] -->|"Watches traffic"| B
Attackers exploit unencrypted traffic in several ways:
- Eavesdropping - Reading data as it travels
- Man-in-the-middle - Intercepting and possibly modifying data
- Session hijacking - Stealing session cookies to impersonate users
- Credential theft - Capturing login forms sent over HTTP
TLS encrypts traffic in transit and detects changes to it, which blocks network eavesdropping and tampering. It cannot protect a compromised client or server, or a session cookie stolen from an endpoint.
Symmetric vs Asymmetric Encryption
TLS needs to encrypt everything sent between two machines that have never met before, with no shared key already in place. That single constraint drives the entire encryption design. Two different schemes solve two different parts of the problem, and TLS wires them together. The two sections below break each type down individually.
Symmetric encryption uses one shared secret key for both encrypt and decrypt. AES and ChaCha20 are the common choices. They run fast enough to encrypt gigabytes per second, which is why the actual data transfer uses them. The catch: both sides need the same key, and sending a key over an open network is exactly what the encryption is supposed to protect.
Public-key cryptography uses related public and private keys, but each algorithm has a specific role. RSA can encrypt or sign, ECDSA signs, and ECDHE lets two parties derive a shared secret. TLS uses signatures to authenticate the handshake and ephemeral Diffie-Hellman for key agreement; modern TLS does not encrypt bulk data with public keys.
| Aspect | Symmetric (AES, ChaCha20) | Public-key (RSA, ECDSA, ECDHE) |
|---|---|---|
| Key use | Same secret encrypts/decrypts | Algorithm-specific key pair operations |
| Speed | Fast (GB/s on modern CPUs) | More expensive than symmetric encryption |
| Key distribution | Both sides need the secret | Public key can be shared openly |
| Use in TLS | Bulk data encryption | Key agreement and authentication |
| Key size for security | 128-256 bits | Depends on algorithm and security level |
TLS combines these techniques. In modern TLS, ephemeral Diffie-Hellman key agreement derives a shared secret, while the server’s certificate and handshake signature authenticate the server. Both sides derive traffic keys from the shared secret, then use symmetric encryption for application data.
This split explains why TLS 1.3 removed static RSA key transport but still allows RSA and ECDSA certificates for signatures. Ephemeral key agreement happens during the handshake; symmetric encryption handles application data afterward.
Symmetric Encryption
Symmetric encryption uses the same key to encrypt and decrypt. It is fast and efficient for large data transfers.
Problem: how do both parties get the same secret key without someone else intercepting it?
// Symmetric encryption example
const key = "shared-secret-key-12345";
const encrypted = encrypt(plaintext, key); // One operation
const decrypted = decrypt(encrypted, key); // Same key reverses it
Asymmetric Encryption
Public-key algorithms use a key pair, but not all of them encrypt data. For example, RSA supports encryption and signatures, ECDSA signs, and ECDHE derives a shared secret.
// Asymmetric encryption example
const { publicKey, privateKey } = generateKeyPair();
const encrypted = encrypt(plaintext, publicKey); // Anyone can encrypt
const decrypted = decrypt(encrypted, privateKey); // Only the private key holder can decrypt
Public-key operations are generally more expensive than symmetric encryption. TLS uses ephemeral key agreement to derive traffic keys and signatures to authenticate the handshake; the public key can be shared while the private key stays protected.
TLS Handshake & Protocol
TLS Handshake
The TLS handshake sets up a secure connection. The exact steps depend on the TLS version and cipher suite, but here is what TLS 1.2 does:
sequenceDiagram
participant Client
participant Server
Note over Client,Server: TLS 1.2 full handshake using ephemeral ECDHE
Client->>Server: ClientHello (versions, cipher suites, client key share)
Server->>Client: ServerHello (selected version and suite)
Server->>Client: Certificate
Server->>Client: ServerKeyExchange (signed ephemeral key share)
Server->>Client: ServerHelloDone
Client->>Server: ClientKeyExchange (client ephemeral key share)
Client->>Server: ChangeCipherSpec, Finished
Server->>Client: ChangeCipherSpec, Finished
Note over Client,Server: Both derive the shared secret; application data follows
With ECDHE, both sides derive the same shared secret from their ephemeral key pairs; the secret itself is never sent over the network. The TLS key schedule derives traffic keys from that secret and the handshake transcript. Older RSA key-transport handshakes instead sent an encrypted premaster secret.
TLS 1.3 Improvements
TLS 1.3 simplified the handshake:
sequenceDiagram
participant Client
participant Server
Note over Client,Server: Full TLS 1.3 handshake
Client->>Server: ClientHello (supported versions and key share)
Server->>Client: ServerHello (key share)
Server->>Client: EncryptedExtensions, Certificate, CertificateVerify, Finished
Client->>Server: Finished
Note over Client,Server: Application data follows after about 1 RTT
A full TLS 1.3 handshake takes about 1 RTT. Eligible resumptions can send early data in the first flight, but the handshake continues; TLS 1.3 also removed static RSA key transport and obsolete cipher suites.
TLS 0-RTT Resumption
TLS 1.3 introduced 0-RTT (zero round trip) resumption, letting a client send data on the first flight for returning connections.
sequenceDiagram
participant Client
participant Server
Note over Client: Previous session ticket available
Client->>Server: ClientHello + replayable early data
Server->>Client: Accept or reject early data; continue handshake
Note over Client,Server: Early data is sent before the handshake completes
The client can use a session ticket from an earlier handshake to encrypt eligible early data alongside its ClientHello. This sends application data before the server has completed the new handshake; it does not skip the handshake, and the server can reject the early data.
How 0-RTT works:
1. First connection: Full handshake, session ticket stored
2. Reconnection: ClientHello + early_data + encrypted ticket
3. Server validates ticket, derives keys, decrypts early_data
4. If accepted, the server may respond before the handshake completes; sending early data needs no extra handshake RTT
Replay risk: A captured 0-RTT request may be accepted more than once. Choose requests by their actual side effects, not just their HTTP method: GET is not automatically safe if the handler changes state, and idempotency alone may not cover every application effect. Do not send an operation in early data unless the application is designed to tolerate replay and the server handles rejected early data safely.
When to use 0-RTT:
- Read-only requests whose repeated processing has no harmful side effects
- Operations protected by application-level replay handling, such as a deduplication or idempotency key
- Requests where the server and client have a defined fallback if early data is rejected
When to avoid 0-RTT:
- Payments or other operations that must not be repeated unless the application has replay protection
- State changes without deduplication or idempotency controls
- Requests whose effects cannot safely be repeated
Perfect Forward Secrecy
Forward secrecy means compromise of a long-term authentication key does not reveal traffic keys from completed sessions that used ephemeral Diffie-Hellman and erased their session secrets. Static RSA key transport and TLS 1.3 PSK-only mode do not provide this protection; 0-RTT early-data keys also lack full forward secrecy.
graph LR
A[Session 1 Key<br/>Ephemeral] --> B[Derived from<br/>DH Exchange]
C[Session 2 Key<br/>Ephemeral] --> B
D[Server Private Key<br/>NOT used for sessions] -.->|cannot derive| A
D -.->|cannot derive| C
How ECDHE provides PFS:
// ECDHE key exchange - each session uses fresh ephemeral keys
const crypto = require("crypto");
// Server generates ephemeral key pair for this session only
const serverEphemeral = crypto.generateKeyPairSync("x25519");
// Client generates ephemeral key pair
const clientEphemeral = crypto.generateKeyPairSync("x25519");
// Each side derives shared secret - never transmitted
const sharedSecret = crypto.diffieHellman({
privateKey: serverEphemeral.privateKey,
publicKey: clientEphemeral.publicKey,
});
// Session key derived from shared secret - server private key
// was never used, so compromising it doesn't expose this session
Key exchange and forward secrecy:
| TLS 1.2 key exchange | Authentication | PFS? | Notes |
|---|---|---|---|
| ECDHE | RSA or ECDSA certificate signature | Yes | Ephemeral key agreement; certificate authenticates the handshake |
| DHE | RSA or ECDSA certificate signature | Yes | Ephemeral finite-field key agreement |
| Static RSA | RSA certificate | No | Legacy key transport; removed from TLS 1.3 |
TLS 1.3 removes static RSA key transport. Full handshakes and PSK resumptions combined with (EC)DHE provide forward secrecy; PSK-only key establishment does not, and 0-RTT early-data keys lack full forward secrecy.
With legacy static RSA key transport, an attacker who recorded traffic could decrypt it later if the server’s private key was compromised. Ephemeral key agreement prevents that retrospective decryption after session secrets are erased.
Certificates & Cipher Suites
Certificates
TLS certificates prove that a server is who it claims to be. Certificates are issued by Certificate Authorities (CAs).
Certificate Structure
A certificate contains:
- Subject (domain name)
- Issuer (CA name)
- Public key
- Validity period (not before, not after)
- Signature from the CA
# You can view certificate details with openssl
openssl s_client -connect example.com:443 -showcerts
Certificate Chains
Browsers verify certificates through a chain of trust:
graph TD
A[Root CA<br/>Browser trusted] --> B[Intermediate CA<br/>Issued by Root]
B --> C[Your Server Certificate<br/>Issued by Intermediate]
The browser already trusts the Root CA. The Root CA signed the Intermediate CA’s certificate. The Intermediate CA signed your server certificate. This chain of trust verifies your certificate.
Self-Signed Certificates
For testing, you can create self-signed certificates. Browsers do not trust them by default, but they encrypt traffic the same way.
# Generate a self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
Cipher Suites
A cipher suite defines the TLS record-layer AEAD algorithm and the hash used with HKDF. TLS 1.3 negotiates key agreement and certificate signatures separately. The specification defines five TLS 1.3 cipher suites:
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256
Each suite specifies:
- The AEAD bulk cipher (such as AES-GCM or ChaCha20-Poly1305)
- The hash used by the TLS key schedule (such as SHA-256 or SHA-384)
Key agreement and certificate signature algorithms are negotiated separately in TLS 1.3.
Older TLS versions had dozens of cipher suites, many with known vulnerabilities. TLS 1.3 defines five cipher suites, with key exchange and certificate signature algorithms negotiated separately.
RSA vs ECDSA Performance Comparison
TLS 1.3 removed static RSA key transport but still permits RSA signatures for certificate authentication. ECDSA certificates are smaller than comparable RSA certificates, while client compatibility and hardware support vary. Choose algorithms based on the clients you serve and benchmark the TLS terminator.
Signature size comparison:
| Algorithm | Key Size | Signature Size | Security Level |
|---|---|---|---|
| RSA 2048 | 2048 bits | 256 bytes | ~112 bits |
| RSA 4096 | 4096 bits | 512 bytes | ~140 bits |
| ECDSA P-256 | 256 bits | 64 bytes | ~128 bits |
| ECDSA P-384 | 384 bits | 96 bytes | ~192 bits |
When to use RSA:
- Compatibility with very old clients (Windows XP SP3, Java 7)
- Hardware tokens that only support RSA
- Environments where ECDSA is not yet supported
When to use ECDSA:
- New certificate deployments
- Performance-critical applications
- Mobile devices (smaller certs = less bandwidth)
- TLS 1.3 deployments (static RSA key transport removed)
Migration path: If you have RSA certificates today, you can gradually transition to ECDSA. Most CAs support both in a chain, and most modern clients prefer ECDSA when available.
HTTPS in Practice
HTTPS behavior and certificate validation
HTTPS in Action
HTTPS is HTTP over TLS. The connection starts as a TCP handshake, then the TLS handshake, then the HTTP request.
sequenceDiagram
participant Browser
participant Server
Browser->>Server: TCP SYN
Server->>Browser: SYN-ACK
Browser->>Server: ACK
Note over Browser,Server: TCP handshake complete
Note over Browser,Server: Full TLS 1.3 handshake
Browser->>Server: ClientHello with key share
Server->>Browser: ServerHello and encrypted server flight
Browser->>Server: Finished
Note over Browser,Server: TLS handshake complete after about 1 RTT
Browser->>Server: HTTPS GET /api/data
Server->>Browser: 200 OK (encrypted)
Port 443 is the standard for HTTPS. Port 80 carries HTTP.
Mixed Content
When a page loaded over HTTPS includes resources over HTTP, that is mixed content. The unencrypted resources can be intercepted or modified, undermining the page’s security.
<!-- Bad: HTTP resource on HTTPS page -->
<img src="http://example.com/image.png" />
<!-- Good: HTTPS resource -->
<img src="https://example.com/image.png" />
Modern browsers block active mixed content (scripts, iframes) automatically. Passive content like images may still load, just with warnings in the console.
Certificate Validation
When your browser connects to a server, it validates the certificate:
- Check the certificate is not expired
- Verify the signature chain leads to a trusted CA
- Check the domain name matches the certificate
- Check for revoked certificates (via CRL or OCSP)
// Node.js validates certificates by default
const https = require("https");
https.get("https://example.com", (res) => {
// Certificate is automatically validated
});
For production systems, proper certificate validation is critical. Never disable validation in production code.
Certificate Transparency and monitoring
Certificate Transparency
Certificate Transparency (CT) makes publicly trusted certificates visible in append-only logs so domain owners and monitors can detect unexpected issuance. CT supports investigation and response; it does not prevent a CA from issuing a certificate or stop an attacker from using one.
Certificate Transparency Log Monitoring
graph TD
A[CA Issues Certificate] --> B[CT Log Server<br/>append-only database]
B --> C[Monitors scan logs<br/>for your domain]
C --> D[Alert if unexpected<br/>certificate appears]
Rogue Certificate Detection
graph TD
E[Unexpected certificate<br/>is issued] --> F[CT log records it]
F --> G[Monitor alerts owner<br/>to investigate and respond]
How CT works:
# View CT PreCertificate log entries for a domain
# Certificates are submitted to multiple independent logs
certspotter -d example.com
# Or use crt.sh to search for all issued certificates
curl -s "https://crt.sh/?q=example.com&output=json" | jq .
# Check SCT (Signed Certificate Timestamp) presence
echo | openssl s_client -connect example.com:443 2>/dev/null | \
openssl x509 -noout -text | grep -A 1 "Signed Certificate Timestamp"
The DigiNotar breach in 2011 showed the harm a fraudulent certificate can cause. CT improves visibility by requiring publicly trusted certificates to be logged under browser policies; domain monitors can alert on unexpected issuance, but teams still need an incident response plan.
SCT delivery methods:
| Method | How client gets SCT | Pros | Cons |
|---|---|---|---|
| X.509 extension | SCT embedded in certificate | Self-contained | Certificate must be reissued |
| TLS extension | SCT sent during TLS handshake | No cert changes | Extra round trip |
| OCSP stapling | SCT stapled with OCSP response | Combined validation | Complex implementation |
Browser HTTPS policy
HSTS Preload Deep Dive
HSTS (HTTP Strict Transport Security) tells browsers to only connect via HTTPS. The preload list goes further—browsers ship your domain as HTTPS-only by default, before any visit.
# Standard HSTS - requires first visit to learn
Strict-Transport-Security: max-age=31536000; includeSubDomains
# HSTS Preload - baked into browsers
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Requirements for preload submission:
1. max-age must be at least 63072000 (2 years)
2. includeSubDomains must be present
3. preload flag must be set
4. Redirect all HTTP to HTTPS on the same host
5. Serve valid certificates on all subdomains
6. Serve a valid certificate chain (not self-signed)
Submit at hstspreload.org. Preload removal is not immediate because browsers update their lists on release cycles; check the current removal process before submitting.
Check preload status:
# Check if a domain is preloaded
curl -s "https://hstspreload.org/api/v2/entries" | \
jq '.[] | select(.name == "example.com")'
Trade-off analysis for preload:
| Factor | Without Preload | With Preload |
|---|---|---|
| First visit protection | No | Yes |
| Removal speed | Fast (update DNS) | Slow (6-12 months) |
| Subdomain requirements | Flexible | All must support HTTPS |
| Risk of lockout | Low | High if misconfigured |
Certificate Providers & mTLS
Let’s Encrypt and Free Certificates
Let’s Encrypt began issuing certificates in 2015 and made public certificate issuance free and automatable through ACME (Automated Certificate Management Environment).
# Certbot automates certificate issuance and renewal
certbot --webroot -w /var/www/html -d example.com -d www.example.com
Let’s Encrypt certificates are publicly trusted like other certificates issued under Web PKI. They currently have 90-day lifetimes, so configure renewal automation and alert on failures rather than assuming renewal will succeed.
When to Use TLS/HTTPS
Reach for TLS/HTTPS when you transmit any sensitive data, your application requires user authentication, or browsers access your service. Also when you need to protect against man-in-the-middle attacks, your service handles API calls from external clients, or compliance requires encryption (PCI-DSS, HIPAA, GDPR).
TLS protection matters most when the threat model is real. Any login or authentication flow sends credentials over the wire — if that connection is unencrypted, anyone sharing the network can capture them. Public WiFi is the obvious case, but corporate networks and compromised routers are just as dangerous.
API endpoints handling user data need TLS too. Session tokens, personal information, business data — all of it. Even services locked behind a firewall are not safe: the Sony and Yahoo breaches both started from internal network compromise.
For browser-accessible services, HTTPS is non-negotiable. Modern browsers flag HTTP sites as insecure, and users notice. Credibility alone is enough reason.
Compliance environments almost always require encryption. PCI-DSS for cardholder data, HIPAA for health records, GDPR for personal data — TLS is the baseline answer in each case. If you are subject to any of these, TLS is not optional.
Service-to-service calls inside cloud environments also need protection. You often cannot control the full network path between microservices. AWS, GCP, and Azure all recommend TLS for internal communication.
If the data has value to someone other than the sender and receiver, encrypt it.
When Not to Use TLS
Keep TLS enabled for production traffic, including calls inside private networks. Treat these as temporary or isolated exceptions:
- A legacy client cannot support a currently secure TLS version. Isolate it and plan an upgrade.
- Local development traffic needs inspection. Use a development proxy or test certificate; do not disable validation in production.
TLS has a processing cost, but cleartext production traffic exposes data to anyone who can observe the network. Measure the cost at your TLS termination point and tune it before considering an exception.
When to Use Mutual TLS (mTLS)
mTLS requires both client and server to present certificates. Use it for service-to-service communication in microservices, API access where you want to verify client identity, IoT devices where certificates replace passwords, and zero-trust network architectures.
Standard TLS authenticates the server only. The client knows who it is talking to, but the server has no way to verify which client is connecting. mTLS closes that gap — both sides prove their identity through certificates signed by a shared CA.
In a service mesh, any individual service can be compromised. mTLS makes sure service A only accepts connections from services B and C, which have valid certificates — not from a compromised service D that somehow ended up on the same network.
API keys can leak through repositories, logs, or environment variables. A client certificate is sent in the TLS handshake, but its private key is not; the client proves possession of that key. Protect private keys and support rotation and revocation, because a copied key can be reused until the certificate expires or is revoked.
IoT devices often cannot use passwords securely. No keyboard for input, no guarantee of secure storage. Hardware-backed secure elements can make private-key extraction harder, though compromised software may still ask the device to use the key.
Zero-trust means verifying every connection, not trusting the network. mTLS is how that principle works at the TLS layer.
mTLS is not free. You need a CA that issues client certificates, a rotation strategy, and revocation handling. The operational overhead is real and only makes sense when you need cryptographic proof of client identity on every connection.
Trade-off Analysis
TLS Version Comparison
| Factor | TLS 1.0/1.1 | TLS 1.2 | TLS 1.3 |
|---|---|---|---|
| Handshake round trips | About 2 RTTs | About 2 RTTs | 1 RTT; eligible resumptions can send 0-RTT early data |
| Forward secrecy | Depends on key exchange | Depends on key exchange | (EC)DHE modes provide it; PSK-only does not |
| Cipher suites | Obsolete, insecure options | Broad algorithm set | Five TLS 1.3 suites defined |
| 0-RTT data | Not supported | Not supported | Eligible PSK resumptions; replayable |
| Static RSA key transport | Supported | Supported | Removed |
| Protocol status | Deprecated | Supported with secure configuration | Current version |
| Client compatibility | Legacy systems | Most systems | Modern systems |
Certificate Type Comparison
| Factor | Self-Signed | Let’s Encrypt | Commercial CA |
|---|---|---|---|
| Cost | Free | Free | Varies |
| Trust level | Not publicly trusted | Publicly trusted | Publicly trusted |
| Validity period | Set locally | 90 days | Subject to current public-CA limits |
| Renewal automation | Manual | ACME (automated) | Varies |
| Support | None | Community | Vendor support |
| Use case | Private testing | Publicly trusted sites | Validation/support requirements |
Publicly trusted TLS certificate maximum lifetimes depend on the issuance date and current CA/Browser Forum rules. Check the Baseline Requirements before setting renewal schedules, and automate renewal well before expiry.
Encryption Algorithm Comparison
| Record cipher | Key Size | Typical use |
|---|---|---|
| AES-128-GCM | 128 bit | TLS record encryption |
| AES-256-GCM | 256 bit | TLS record encryption |
| ChaCha20-Poly1305 | 256 bit | TLS record encryption, including mobile clients |
RSA and ECDSA are signature algorithms, not TLS record-encryption algorithms. Their compatibility and performance depend on client support and the server implementation.
Production Failure Scenarios
| Failure | Impact | Mitigation |
|---|---|---|
| Certificate expired | Browser warnings, users cannot connect, revenue loss | Set up automated renewal (certbot/ACME); alert 30 days before expiry |
| Weak cipher suite enabled | Weakens confidentiality or handshake security | Remove obsolete algorithms; use supported AEAD suites and ephemeral key exchange |
| Self-signed certificate in production | Public clients fail normal trust validation | Use a publicly trusted CA for public sites |
| Certificate chain incomplete | Some clients fail to validate; intermittent outages | Serve the leaf certificate and required intermediates; omit the trusted root in most cases |
| Private key compromised | Attacker can impersonate your server | Rotate immediately; have a key rotation plan ready |
| Mixed content on HTTPS page | Unencrypted resources load; security warnings | Serve all resources over HTTPS; set up CSP |
| OCSP stapling not configured | Clients that check status may need a separate lookup | Enable stapling where supported; monitor response freshness |
| TLS 1.3 disabled | Fewer modern handshake options; compatibility may be limited | Enable TLS 1.3 where supported and retain a secure TLS 1.2 configuration |
TLS Observability Checklist
- Certificate lifecycle: Alert before a certificate expires and when renewal fails. Check what each edge or host actually serves: the hostname, expiry date, and full chain.
- Validation failures: Track handshake failures by reason, including expired or mismatched certificates, unknown issuers, and missing intermediates. Group results by hostname and client; failures limited to one client family may point to a trust-store or chain compatibility issue.
- Handshake latency: Measure successful and failed handshakes separately, including p50 and p95 duration. A rise can point to slow revocation checks, overloaded TLS termination, or extra network round trips.
- Version and cipher negotiation: Record negotiated TLS versions and cipher suites at the edge and origin. Alert when connections fall below your minimum version, an unexpected cipher appears, or negotiation failures rise after a configuration change.
Security and Compliance Notes
TLS protects data in transit and helps authenticate the server; it does not by itself make an application compliant. Map encryption settings to the rules that apply to your data and jurisdiction, then document where TLS terminates and how traffic is protected between the edge and application services.
- Limit access to private keys, keep them out of source control and logs, and rotate them after suspected exposure.
- Keep supported TLS versions and cipher suites aligned with your security baseline; record approved exceptions for legacy clients and set a plan to remove them.
- Restrict access to handshake and audit logs, redact credentials and personal data, and set retention periods that match applicable requirements.
- Review certificate renewal, revocation, and incident procedures so teams can replace a compromised key without leaving endpoints unprotected.
Common Pitfalls / Anti-Patterns
Disabling Certificate Validation
Never disable certificate validation in production code, not even for simplicity.
// DANGEROUS - Never do this
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
// Instead, use proper certificates
const https = require("https");
const options = {
cert: fs.readFileSync("/path/to/cert.pem"),
key: fs.readFileSync("/path/to/key.pem"),
ca: fs.readFileSync("/path/to/ca.pem"), // Certificate authority chain
};
Using Self-Signed Certificates in Production
Self-signed certificates work for testing but break trust in browsers.
# Self-signed is OK for development
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
# For production, use Let's Encrypt (free)
certbot --webroot -w /var/www/html -d example.com
Not Including Full Certificate Chain
Missing intermediate certificates cause validation failures.
# Check certificate chain
openssl s_client -connect example.com:443 -showcerts
# The server should send the leaf certificate and required intermediates.
# The client should already have a trusted root in its trust store.
Ignoring Mixed Content Warnings
HTTPS pages loading HTTP resources are vulnerable.
<!-- BAD - HTTP resource on HTTPS page -->
<script src="http://example.com/app.js"></script>
<!-- GOOD - All resources use HTTPS -->
<script src="https://example.com/app.js"></script>
Not Implementing HSTS
Without HSTS, attackers can strip HTTPS and intercept traffic.
# Good HSTS header
Strict-Transport-Security: max-age=31536000; includeSubDomains
# Even better - preload HSTS
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Best Practices Summary
Server Configuration
Enable TLS 1.3 where clients support it and retain a secure TLS 1.2 configuration for compatibility. Disable TLS 1.0 and 1.1 unless a documented legacy requirement remains; track and isolate that exception. Prefer modern AEAD suites and ephemeral key exchange, and verify the configuration against current guidance for your server.
Enable HSTS after HTTPS works across the domain. Submit for preload only when every included subdomain can serve a valid certificate and remain HTTPS-only; preload removal can take time.
Configure OCSP stapling where supported and monitor response freshness. Clients that use the stapled response can avoid a separate status lookup; it does not replace hostname, chain, or expiry validation.
Set up certificate transparency monitoring. You can use crt.sh or a paid monitor to alert you whenever a certificate is issued for your domain.
Managing Certificates
Automate renewal. Certbot + Let’s Encrypt is free and handles 90-day renewals. Set your alert threshold at 30 days, not 7—when expiration hits, it is already too late.
Serve the leaf certificate and required intermediate certificates; clients normally already have the trusted root. Missing intermediates can cause validation failures that vary by client trust store.
Rotate keys regularly and store them separately from application code. Use a secrets manager. Never commit a private key to a repository.
Consider ECDSA certificates for their smaller signatures, and retain RSA where client compatibility requires it. Test the actual clients and termination stack before removing a certificate type.
Application Security
Redirect all HTTP to HTTPS. No exceptions. Mixed content undermines your HTTPS setup—serve everything over TLS.
Set the Secure and HttpOnly flags on session cookies. Without them, cookies leak through non-HTTPS connections.
Use certificate pinning in a native client only when the threat model justifies its operational cost. Pin public keys with a backup and a tested rotation/recovery plan; normal Web PKI validation remains necessary.
Monitoring
Watch TLS version distribution by client population. Investigate unexpected legacy traffic, but set migration thresholds based on your support requirements rather than a universal percentage.
Alert on certificate expiration (30 days), handshake failure spikes, and unusual downgrade attempts. Log handshake failures with cipher suite, TLS version, and client IP for forensics.
Development Practices
Never disable TLS validation in code—not for “internal” services, not for localhost, not for anything. If you think you need to, you are wrong.
Test your TLS configuration with Qualys SSL Labs and testssl.sh. Design your systems to rotate certificates without downtime.
Quick Recap Checklist
- Use supported TLS versions and modern cipher suites.
- Validate the certificate chain and automate renewal.
- Redirect HTTP to HTTPS, enable HSTS, and remove mixed content.
- Restrict 0-RTT to replay-safe requests.
- Monitor certificate expiry and handshake failures.
Interview Questions
Further Reading
- HTTP and HTTPS Protocol — understand the HTTP layer carried over TLS.
- DNS & Domain Management — review how domain names lead clients to the right server.
- Network Security — connect TLS configuration to broader network controls.
- Mutual TLS — explore client certificate authentication in more detail.
Official Specifications
- RFC 8446 - TLS 1.3 - The TLS 1.3 specification
- RFC 5246 - TLS 1.2 - TLS 1.2 specification
- RFC 9325 - Recommendations for TLS and DTLS - Current BCP 195 security recommendations
Certificate Management
-
CA/Browser Forum Baseline Requirements - Current requirements for publicly trusted TLS certificates.
-
Let’s Encrypt Documentation - Free certificate issuance and automation
-
Certbot Documentation - ACME client setup guides
-
Certificate Transparency - Official CT project site
-
crt.sh - Certificate search and monitoring tool
Security Best Practices
- Mozilla SSL Configuration Generator - Hardened server configurations
- Qualys SSL Labs - TLS configuration analyzer
- HSTS Preload List - Submit and check preload status
Tools and Testing
- OWASP TLS Cipher String Knowledge - Security cheat sheet
- testssl.sh - Command-line TLS testing tool
- SSLyze - Python TLS analysis library
Conclusion
TLS protects web traffic from eavesdropping and tampering. SSL came first; TLS is its modern replacement. In current handshakes, the peers use key agreement to derive shared traffic keys, then authenticated encryption protects application data.
Certificates help clients authenticate the server through a trusted chain. TLS 1.3 shortens the full handshake and removes static RSA key transport; forward secrecy depends on the negotiated key-establishment mode.
HTTPS is just HTTP over TLS on port 443.
For how HTTP works at the application layer, see the HTTP/HTTPS protocol post. For DNS and domain security, see the DNS & Domain Management post.
Category
Related Posts
Trace and Secure a Web Request
Trace a web request from DNS through routing, TCP, TLS, and HTTP with safe commands, then classify failures and review least-privilege security evidence.
Forward and Reverse Proxies: Routing, Trust, and Use Cases
Learn how forward and reverse proxies handle HTTP traffic, CONNECT tunnels, TLS termination, caching, routing, trusted headers, and production failures.
Network Ports and Firewalls
Learn how TCP and UDP ports, listening sockets, and firewall rules shape backend reachability, with practical examples for safer production deployments.