SSL/TLS is the encryption protocol that protects data in transit over networks. Every HTTPS connection, VPN, and secure communication relies on SSL/TLS to keep data confidential and authentic.
What is SSL/TLS?
SSL (Secure Sockets Layer) and TLS (Transport Layer Security) are cryptographic protocols:
Unencrypted (HTTP):
Client: "Here's my password"
123456 (visible to everyone!)
Encrypted (HTTPS with TLS):
Client: "Here's my password"
◆■▲●◇■▲● (encrypted gobbledygook)
SSL vs TLS:
- SSL 3.0 (1996) — Insecure, deprecated
- TLS 1.0 (1999) — Legacy, should avoid
- TLS 1.1 (2006) — Outdated
- TLS 1.2 (2008) — Current standard
- TLS 1.3 (2018) — Modern, recommended
Everyone calls it "SSL" even though TLS is technically correct. TLS is newer and more secure.
How TLS Works
TLS Handshake (happens before data transfer):
Client Server
├─ Hello (supported ciphers) ──────→
├←─ Hello + Certificate ────────────┤
├─ Verify certificate (trust chain)
├─ Generate shared secret ──────────→
├← Handshake complete ─────────────┤
│
└─ All data encrypted ←─────────────→
Key Agreement:
- Client & server agree on encryption algorithm
- Exchange public keys
- Both derive same shared secret (symmetric key)
- Use shared secret to encrypt all data
Why two types of encryption?
Asymmetric (slow, for key exchange):
- Public key: anyone can use
- Private key: only owner knows
- Safe to share public key over internet
Symmetric (fast, for data):
- Same key for encryption & decryption
- Both sides know the key (agreed during handshake)
- Fast enough for bulk data
Digital Certificates
Certificate proves the server is who it claims to be:
Owner: api.example.com
Issued by: Letsencrypt (certificate authority)
Expires: 2026-04-09
Public Key: -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0B...
Fingerprint: F3:3E:D8:D7:...
Certificate Chain:
Root CA (self-signed, trusted)
└─ Intermediate CA (signed by root)
└─ Server Certificate (signed by intermediate)
Browser verification:
- Server sends certificate
- Browser checks signature chain
- Verifies domain matches
- Checks expiration date
- If all good → green lock 🔒
Certificate Types
| Type | Coverage | Price | Use |
|---|---|---|---|
| Single Domain | api.example.com only | Free-$50/yr | Single service |
| Wildcard | *.example.com | $50-$200/yr | All subdomains |
| Multi-SAN | Multiple domains | $100-$300/yr | Multiple domains |
| EV | With company verification | $150-$250/yr | Enterprise |
Let's Encrypt = Free certificates!
# Get free 90-day certificate
certbot certonly --standalone -d example.com
# Automatically renews before expiryCreating SSL/TLS Certificates
Generate Self-Signed Certificate (for testing):
# Generate private key (2048 bits)
openssl genrsa -out private.key 2048
# Generate certificate (valid 365 days)
openssl req -new -x509 -key private.key \
-out certificate.crt -days 365 \
-subj "/CN=example.com"
# View certificate
openssl x509 -in certificate.crt -text -nooutGenerate Certificate Signing Request (for CA):
# Create private key
openssl genrsa -out private.key 2048
# Create signing request (CSR)
openssl req -new -key private.key \
-out certificate.csr \
-subj "/CN=example.com/O=Company/C=US"
# Send CSR to Certificate Authority
# CA verifies identity, returns signed certificateConfiguring TLS on Server
Nginx Example:
server {
listen 443 ssl http2;
server_name api.example.com;
# Certificate files
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
# TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Redirect HTTP to HTTPS
location / {
proxy_pass http://backend:8080;
}
}
server {
listen 80;
server_name api.example.com;
return 301 https://$server_name$request_uri; # Redirect to HTTPS
}Apache Example:
<VirtualHost *:443>
ServerName api.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/api.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/api.example.com/privkey.pem
SSLProtocol TLSv1.2 TLSv1.3
SSLCipherSuite HIGH:!aNULL:!MD5
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
</VirtualHost>
<VirtualHost *:80>
ServerName api.example.com
Redirect / https://api.example.com/
</VirtualHost>Checking Certificates
View certificate details:
# From server
openssl x509 -in certificate.crt -text -noout
# From live connection
openssl s_client -connect example.com:443Check expiration date:
openssl x509 -in certificate.crt -noout -dates
# Output:
# notBefore=Apr 9 00:00:00 2024 GMT
# notAfter=Apr 9 23:59:59 2025 GMTVerify certificate chain:
openssl verify -CAfile ca-bundle.crt certificate.crt
# Result: OK (valid)
# or: error (problem)Certificate Management
Automated Renewal with Certbot:
# Install certbot
sudo apt-get install certbot python3-certbot-nginx
# Get certificate
sudo certbot certonly --nginx -d example.com
# Automatic renewal
sudo systemctl enable certbot.timer
# Check renewal status
sudo certbot renew --dry-runMonitoring Certificate Expiry:
#!/bin/bash
# Alert if certificate expires in < 30 days
for cert in /etc/letsencrypt/live/*/fullchain.pem; do
expiry=$(openssl x509 -in $cert -noout -dates | grep notAfter)
echo "$cert: $expiry"
doneTroubleshooting TLS
"Certificate not trusted"
1. Check expiration
openssl x509 -noout -dates -in cert.pem
2. Verify domain matches
openssl x509 -noout -subject -in cert.pem
← Should match server hostname
3. Check certificate chain
openssl verify -CAfile ca-bundle.crt cert.pem
4. Reconstruct cert chain
cat server.crt intermediate.crt root.crt > fullchain.pem
"Connection refused on 443"
1. Check if HTTPS server is running
telnet example.com 443
← Should connect
2. Verify firewall allows port 443
sudo ufw allow 443
3. Check server config
grep -A5 "listen 443" /etc/nginx/sites-enabled/*
"Certificate expired"
1. Renew certificate
openssl x509 -req -days 365 \
-in old.csr -signkey private.key \
-out new.crt
2. Deploy new certificate
cp new.crt /path/to/server/cert
systemctl restart nginx
3. Verify renewal
openssl x509 -noout -dates -in new.crt
TLS Best Practices
1. Use Current TLS Version
✓ TLS 1.2 minimum
✓ TLS 1.3 preferred
✗ Never use SSL 3.0, TLS 1.0, TLS 1.1
2. Keep Certificates Valid
✓ Renew before expiry (but not too early)
✓ Monitor expiration dates
✗ Don't let certificates expire
3. Use Strong Ciphers
✓ ECDHE with AES-GCM
✗ Avoid weak ciphers (DES, RC4, MD5)
4. Enable HSTS (force HTTPS):
Strict-Transport-Security: max-age=31536000; includeSubDomains
5. Monitor Certificate Usage
# Check which certificates are deployed
find /etc -name "*.pem" -o -name "*.crt" 2>/dev/null
# List expiration dates
for cert in $(find /etc -name "*.crt" 2>/dev/null); do
echo "$cert: $(openssl x509 -noout -dates -in $cert)"
doneKey Concepts
- SSL/TLS = Encryption protocol for secure communication
- Handshake = Process to establish encrypted connection
- Certificate = Proves server identity
- Certificate Authority (CA) = Issues and signs certificates
- Private key = Keep secret, used for decryption
- Public key = Share openly, used for encryption
- Self-signed = Certificate not issued by CA (for testing)
- Symmetric encryption = Fast, same key for encrypt/decrypt
- Asymmetric encryption = Slow, different public/private keys
- Always use HTTPS with valid certificates in production