Back to blog
Security & Compliancebeginner

HTTPS & TLS — How Your Data Stays Private in Transit

A clear explanation of what happens during a TLS handshake, how certificates work, what root CAs are, and what can still go wrong even when the padlock is green.

LearnixoApril 15, 20269 min read
SecurityHTTPSTLSCertificatesEncryptionPKI
Share:š•

The Problem TLS Solves

When you send an HTTP request, it travels through many machines before reaching its destination — your router, your ISP's infrastructure, backbone routers, and the destination server. Any of those machines could read or modify your data.

TLS (Transport Layer Security) creates an encrypted tunnel between your browser and the server so that:

  1. No one in the middle can read the data (confidentiality)
  2. No one in the middle can modify the data without detection (integrity)
  3. You are actually talking to the real server, not an impersonator (authentication)

HTTPS is simply HTTP running inside a TLS tunnel.


Symmetric vs Asymmetric Encryption

Understanding TLS requires knowing two types of encryption.

Symmetric Encryption

One key encrypts and the same key decrypts. Fast. Used for bulk data transfer.

encrypt("Hello", key="abc123") → "Xq9r#"
decrypt("Xq9r#", key="abc123") → "Hello"

The problem: how do two strangers who have never met agree on a shared key without an eavesdropper learning it? You cannot email it — it could be intercepted.

Asymmetric Encryption

Two keys: a public key you share with anyone, and a private key you never share. Data encrypted with the public key can only be decrypted with the private key.

encrypt("Hello", publicKey) → "Zk7m$"  ← only the private key can undo this
decrypt("Zk7m$", privateKey) → "Hello"

Also works in reverse for signatures: sign with the private key, anyone with the public key can verify it is authentic.

Asymmetric is slow. TLS uses it only to securely agree on a symmetric key, then switches to symmetric for the actual data.


The TLS Handshake — Step by Step

When your browser first connects to https://example.com, this happens before a single byte of HTTP data is sent:

Browser                                    Server
   |                                          |
   |  1. CLIENT HELLO                         |
   |     - TLS version supported              |
   |     - List of cipher suites              |
   |     - Random bytes (client random)  ---> |
   |                                          |
   |  2. SERVER HELLO                         |
   |     - Chosen TLS version                 |
   |     - Chosen cipher suite                |
   |     - Random bytes (server random)       |
   | <---                                     |
   |                                          |
   |  3. CERTIFICATE                          |
   |     - Server's public key                |
   |     - Identity claim (domain name)       |
   |     - Digital signature from a CA   <--- |
   |                                          |
   |  4. Browser validates certificate        |
   |     - Is the CA trusted?                 |
   |     - Is the domain name correct?        |
   |     - Has it expired?                    |
   |     - Has it been revoked?               |
   |                                          |
   |  5. KEY EXCHANGE                         |
   |     - Browser generates a pre-master     |
   |       secret, encrypts with server's     |
   |       public key, sends it          ---> |
   |                                          |
   |  Both sides derive the same session key  |
   |  from: client random + server random     |
   |  + pre-master secret                     |
   |                                          |
   |  6. FINISHED                             |
   |     - Both sides send "Finished"         |
   |     - First message encrypted with       |
   |       the new session key           <--> |
   |                                          |
   |  === All HTTP traffic now encrypted ===  |

With TLS 1.3 (the current version), the handshake is faster — some steps are combined and the round trips are reduced to one, cutting latency.


What a Certificate Contains

A TLS certificate is a digitally signed document. Open any HTTPS site in Chrome, click the padlock, then "Connection is secure" → "Certificate is valid". You will see:

  • Subject: The domain name the certificate is for (e.g., *.example.com)
  • Issuer: The Certificate Authority that signed it (e.g., Let's Encrypt Authority R3)
  • Public Key: The server's asymmetric public key
  • Valid From / Valid To: The certificate's validity period (usually 90 days to 1 year)
  • Serial Number: Unique ID for this certificate
  • Subject Alternative Names (SANs): Additional domains this cert covers
  • Signature Algorithm: e.g., SHA256WithRSA

The digital signature is the key part: the CA used its private key to sign a hash of the certificate contents. Anyone with the CA's public key can verify that signature — and the CA's public key is shipped with every browser and OS.


Certificate Chains and Root CAs

You trust websites because your browser trusts a specific set of root CAs. This is the chain of trust:

Root CA (DigiCert, GlobalSign, Let's Encrypt, etc.)
  └── Intermediate CA (signed by Root CA)
       └── Your Certificate (signed by Intermediate CA)

Browsers come with ~150 root CA certificates pre-installed. You trust those root CAs. The root CA trusts the intermediate CA (because they signed its certificate). The intermediate CA signed your server's certificate. Therefore your browser trusts your server.

If any link in the chain is broken, the browser shows a certificate error and warns the user.

Why intermediates? Root CA private keys are stored in hardware vaults and almost never used. If an intermediate CA is compromised, it can be revoked without invalidating the root.


Let's Encrypt and Free Certificates

Before ~2016, TLS certificates cost money ($10–$300/year). This created a financial barrier that kept much of the web on HTTP.

Let's Encrypt is a free, automated, open Certificate Authority run by the non-profit Internet Security Research Group. It issues 90-day certificates at no cost, automated via the ACME protocol.

Bash
# Get a free certificate with Certbot (Let's Encrypt client)
certbot --nginx -d example.com -d www.example.com
# Certbot proves you control the domain, gets the cert, configures nginx, schedules renewal

Let's Encrypt has issued billions of certificates and is trusted by all major browsers. There is now no excuse not to use HTTPS.

The 90-day expiry is intentional: it forces automation (you cannot manually renew 90-day certs at scale) and limits the blast radius if a certificate is compromised.


HSTS — Strict Transport Security

Even with HTTPS, there is a window of vulnerability: the user's very first request might go out as HTTP before being redirected to HTTPS. An attacker in a man-in-the-middle position can intercept that first HTTP request.

HSTS (HTTP Strict Transport Security) solves this:

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

Once the browser receives this header over HTTPS, it remembers: "for the next 31,536,000 seconds (1 year), always use HTTPS for this domain — never even try HTTP." The browser upgrades HTTP requests to HTTPS internally, before any packet leaves the machine.

HSTS Preloading

The first-visit vulnerability still exists even with HSTS — the very first visit has no HSTS header cached yet. Preloading solves this: you submit your domain to hstspreload.org and browsers ship with a hardcoded list of domains that are HTTPS-only. Your domain is HTTPS-only for every user, even on their first visit, even on a fresh OS install.

Requirements: HTTPS on all subdomains, max-age at least 1 year, includeSubDomains, preload directive. Preloading is permanent — removing from the list takes months to propagate.


Certificate Pinning — Powerful but Risky

Certificate pinning means hardcoding the expected certificate (or its public key hash) into your application. The app refuses to connect unless it sees exactly that certificate.

It defeats man-in-the-middle attacks even from trusted CAs — because even if an attacker gets a fraudulently issued certificate from a CA, your app does not trust it.

However, the risks are severe:

  • If the certificate expires or is rotated and you do not update the app, your app stops working entirely.
  • Mobile app updates can take days or weeks to reach users.
  • Google and Apple have had to warn developers about pinning failures that broke apps for millions of users.

Recommendation: Only use certificate pinning if you have a mature, automated certificate rotation process and can push app updates instantly. For most web applications, HSTS + HSTS preloading is sufficient.


What Can Still Go Wrong with HTTPS

A green padlock does not mean you are safe — it means the transport is encrypted. Several things can still go wrong:

1. Certificate Not Validated (Man-in-the-Middle)

If your code bypasses certificate validation — which many developers do "just for testing" — TLS provides no authentication. An attacker with a self-signed certificate can intercept everything.

C#
// EXTREMELY DANGEROUS — never do this in production
handler.ServerCertificateCustomValidationCallback =
    (message, cert, chain, errors) => true; // accepts any certificate!

Remove this before deploying. Ever. To anywhere.

2. Mixed Content

A page served over HTTPS loads a script or image over HTTP. Browsers block (or warn about) this. If an attacker can modify that HTTP resource, they can inject code into your HTTPS page. Your padlock means nothing if you are loading third-party resources insecurely.

3. Weak Cipher Suites

Older TLS versions (TLS 1.0, 1.1) and weak cipher suites have known vulnerabilities (BEAST, POODLE, BEAST). Force TLS 1.2 at minimum; TLS 1.3 is preferred.

NGINX
# nginx — enforce TLS 1.2 and 1.3 only
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

4. Expired Certificates

An expired certificate causes the browser to show a hard warning that most users will not bypass. Automate renewal (Certbot, cloud provider cert management). Monitor expiry with alerting.

5. Compromised CA

If a CA is compromised and issues fraudulent certificates, your TLS connection can be intercepted even though it looks valid. This is rare — CAs go through regular audits — but has happened (DigiNotar, 2011). Mechanisms like Certificate Transparency (CT) and CAA DNS records reduce this risk.


Quick Mental Model

Think of TLS like a sealed envelope with a wax seal:

  • Encryption = the envelope. No one can read the contents.
  • Integrity = the wax seal. You can tell if it was opened.
  • Authentication = the return address, verified by a trusted notary. You know who sent it.

HTTPS does not protect you from bad server-side code, SQL injection, or insecure data storage. It only protects the data while it is moving between the browser and the server. Everything else is your job.

Enjoyed this article?

Explore the Security & Compliance learning path for more.

Found this helpful?

Share:š•

Leave a comment

Have a question, correction, or just found this helpful? Leave a note below.