KAHIBARO
Discord Login Register

22.8. TLS Certificates

Why TLS Certificates Exist

When you visit https://example.com, your browser wants to be sure of two things:

  1. Your connection is encrypted, so others cannot read or modify the data.
  2. You are really talking to example.com, not an attacker.

TLS (Transport Layer Security) is the protocol that encrypts traffic.
A TLS certificate is the digital document that proves the server’s identity and helps set up encryption.

A website can only be considered secure if:

  1. It uses HTTPS (TLS encryption), and
  2. The TLS certificate is valid, not expired, issued by a trusted authority, and matches the domain.

Without a proper TLS certificate, users see browser warnings like “Your connection is not private.”

Basic Concepts and Terminology

Public Key, Private Key, and Certificates

TLS uses public key cryptography:

ItemKept WherePurpose
Private keyOn the server onlyDecrypt data, prove identity
Public keyInside the certificateEncrypt data, verify signatures
CertificateSent to clientsBinds public key to a domain or organization

The certificate is basically:

“The holder of this private key is allowed to use this domain name.”

signed by a Certificate Authority.

If an attacker steals the private key, they can impersonate your site.
So private key protection is critical.

Certificate Authorities (CAs) and Trust

Browsers and operating systems ship with a trust store, a list of trusted CAs.

A Certificate Authority:

Your TLS certificate is trusted only if:

  • It is signed by a CA present in the client’s trust store, or
  • It chains up to such a CA with valid intermediate certificates.

Types of TLS Certificates

By Identity Level

Domain Validated (DV)

Organization Validated (OV)

Extended Validation (EV)

For backend APIs, DV is usually enough.

By Domain Coverage

TypeExample domains covered
Single-domainexample.com or api.example.com
Wildcard*.example.com (api.example.com, shop.example.com)
Multi-domain (SAN)example.com, api.example.com, other-site.com

A wildcard *.example.com does not cover the root example.com itself.
You must explicitly include example.com if you need it.

Certificate Chain and Root Certificates

What Is a Certificate Chain?

A browser does not directly trust your server certificate. It trusts root CAs.

Typical structure:

  1. Root CA certificate
    • Self-signed. Stored in the OS or browser trust store.
  2. Intermediate CA certificate(s)
    • Signed by the root. Used to sign server certificates.
  3. Server (leaf) certificate
    • Your domain’s certificate, signed by an intermediate CA.

On TLS handshake, the server should send:

The browser uses these to build a chain up to a trusted root.

If an intermediate is missing, clients may show errors like:

Self-Signed Certificates

A self-signed certificate is signed by its own private key, not by a CA.

Use self-signed certs only for:

How TLS Handshake Uses Certificates

Here is a simplified view of the TLS handshake with HTTPS:

  1. Client connects to https://example.com on port 443.
  2. Client sends supported protocol versions and cipher suites.
  3. Server responds with:
    • Its certificate (with public key),
    • Intermediate certificates,
    • Chosen cipher suite.
  4. Client verifies the certificate:
    • Signature validates up the chain to a trusted root.
    • Not expired.
    • Not revoked.
    • Domain name matches (example.com).
  5. If all checks pass, client:
    • Creates a random secret key.
    • Encrypts it with the server’s public key.
    • Sends it to the server.
  6. Server decrypts it using its private key.
  7. Both sides now share a session key for fast symmetric encryption.

From this point, the connection is encrypted.

If the certificate is invalid, expired, or does not match the domain, the browser must warn the user.
Users should not ignore these warnings in production environments.

Managing TLS Certificates

Key Files You Will See

On a Linux server with Nginx or similar you typically see:

FileContains
privkey.pemPrivate key for your domain
cert.pemServer certificate for your domain
chain.pemIntermediate certificate(s)
fullchain.pemcert.pem + chain.pem concatenated

Some tools or servers can accept a single file that combines them.

Common Certificate Formats

ExtensionEncodingTypical use
.pemBase64 with headers -----BEGIN CERTIFICATE-----Linux, Nginx, Apache
.crtOften same as .pemGeneric cert file
.keyPrivate key in PEM formatServer private key
.pfx / .p12Binary PKCS#12 formatWindows, some load balancers, Java key stores

Converting often uses openssl, for example:

bash
# Convert PFX to PEM (cert + key)
openssl pkcs12 -in cert.pfx -out cert.pem -nodes

Getting TLS Certificates

Free Certificates with Let’s Encrypt

Let’s Encrypt is a free, automated CA that issues DV certificates.

Typical flow on a Linux server:

  1. Install Certbot:
bash
sudo apt update
sudo apt install certbot python3-certbot-nginx
  1. Request a certificate for your domain (Nginx example):
bash
sudo certbot --nginx -d example.com -d www.example.com

Certbot:

Check renewal status:

bash
sudo certbot renew --dry-run

Paid Certificates

Some organizations still buy certificates from commercial CAs, for example:

The process is similar:

  1. Generate a CSR (Certificate Signing Request) on the server.
  2. Submit CSR to the CA.
  3. Complete domain and / or organization verification.
  4. Download the certificate and intermediate chain.
  5. Configure on the server.

CSR generation example:

bash
# generate a private key
openssl genrsa -out example.com.key 2048
# generate a CSR
openssl req -new -key example.com.key -out example.com.csr

Certificate Lifetimes, Renewal, and Revocation

Expiration and Renewal

Certificates have a validity period:

If the expiration date passes, clients will reject the cert.

Always set up automatic renewal for TLS certificates.
An expired certificate is a very common and easily avoidable production outage.

For Let’s Encrypt, Certbot handles:

bash
sudo certbot renew

You still must reload or restart your web server after renewal if the tool does not do it automatically.

For example, with Nginx:

bash
sudo systemctl reload nginx

Revocation

If a private key is leaked or a domain is no longer under your control, you must revoke the certificate.

Modern browsers mainly use OCSP or OCSP stapling.

As a backend developer, if you suspect key compromise:

  1. Generate a new key and CSR.
  2. Get a new certificate.
  3. Request revocation of the old certificate from the CA.

Common Certificate Problems and Errors

Common Browser Errors

Error message (example)Likely cause
“Your connection is not private”Multiple possible issues
“Certificate has expired”Certificate validity end date passed
“Certificate not yet valid”System time incorrect or wrong notBefore date
“Certificate is not trusted”Unknown CA or missing chain
“Hostname mismatch” or “SEC_ERROR_BAD_CERT_DOMAIN”Cert’s CN/SAN does not match domain

Check using tools like:

bash
openssl s_client -connect example.com:443 -servername example.com

or online services like SSL Labs’ SSL Server Test.

Hostname Mismatch Example

If your certificate is issued for api.example.com and you use it for example.com, browsers will show a domain mismatch error.

Fix: Request a certificate that covers all required hostnames, for example:

TLS Certificates in Reverse Proxies and Load Balancers

Termination at the Reverse Proxy

In many backend setups:

Typical pattern:

  1. Client connects to https://api.example.com:443 with TLS.
  2. Nginx terminates TLS using the certificate.
  3. Nginx forwards traffic to your app over HTTP, for example http://127.0.0.1:8000.

In this case:

This is called TLS termination or SSL termination at the reverse proxy.

End-to-End Encryption

Sometimes, especially in multi-server or multi-datacenter setups, you want encryption:

Then each hop uses its own certificate.

For internal traffic you might:

Security Best Practices for TLS Certificates

Strong Keys and Algorithms

Nginx example snippet:

nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

Private Key Protection

Never commit private keys to Git or store them in public places.
Limit file permissions to the web server user only.

On Linux:

bash
chown root:root /etc/ssl/private/example.com.key
chmod 600 /etc/ssl/private/example.com.key

HTTP to HTTPS Redirect

Always redirect HTTP to HTTPS so all traffic is encrypted.

Nginx example:

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

HSTS (HTTP Strict Transport Security)

HSTS tells browsers to always use HTTPS for your domain, which helps prevent downgrade attacks.

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

Use with care, especially includeSubDomains, because once enabled for a long max-age it is hard to roll back.

Example: Nginx Configuration Using a TLS Certificate

Assume you have:

Example Nginx server block:

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name example.com www.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 HIGH:!aNULL:!MD5;
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

This config shows how your certificate ties into real-world backend deployment.

Summary

Views: 5

Comments

Please login to add a comment.

Don't have an account? Register now!