Lesson 4 · 15 min read

HTTPS, SSL and TLS: Certificates, Let’s Encrypt, ACM

What the padlock in your address bar actually proves, how a free certificate gets issued, and the exact commands to put HTTPS on your own EC2 server.

What you'll learn in this lesson

  1. Concept — postcard vs sealed box
  2. What actually leaks without HTTPS
  3. The three jobs HTTPS does
  4. Key terms explained
  5. The chain of trust
  6. The handshake, step by step
  7. Two ways to get a free certificate
  8. Real example — HTTPS on EC2
  9. The Nginx config afterward
  10. Common errors you will hit
  11. Verifying it yourself
  12. What HTTPS does not do
  13. Practice task before Lesson 5
  14. Conclusion

Concept — postcard vs sealed box

HTTP (HyperText Transfer Protocol) is the set of rules that browsers and servers use to talk. It sends everything as plain readable text. HTTPS is HTTP made safe.

  • HTTP is like a message written on a postcard. Every postman and every sorting office that touches it can read it. Nothing needs to be opened.
  • HTTPS is the same message inside a locked box. Only the receiver has the key. People can still see the box travelling and who it is addressed to. But they cannot read what is inside.

The technology that does the locking is TLS (Transport Layer Security). You will often hear “SSL certificate”. SSL was the older version of the same idea. It is now obsolete, but the name stuck. When someone says SSL today, they almost always mean TLS.

What actually leaks without HTTPS

Say your app is live on EC2 with no HTTPS, and a customer logs in from a café WiFi. This is what travels across that network:

POST /api/login HTTP/1.1
Host: yourapp.com
Content-Type: application/json

{"email":"user@example.com","password":"Acme@2026"}
Readable by anyone on the same WiFi

Anyone on the same WiFi can read every character, using free tools. The password is not the only leak. The session cookie sent afterwards leaks too. A thief can copy it and be logged in as that user without knowing the password.

With HTTPS enabled, the exact same login sends this instead:

17 03 03 00 45 8f a3 d9 e2 b1 7c 4f 6a 2d 91 ...

These are meaningless bytes. It is the same request and the same data, but nobody can read it.

Over HTTP
Browser sends login
Anyone on the WiFi reads:
user@example.com
Acme@2026
every character readable
Your server
Over HTTPS
Browser sends login
Anyone on the WiFi reads:
8f a3 d9 e2 b1 7c 4f
6a 2d 91 …
nothing useful
Your server
The data does not change. Only whether anyone in between can understand it.

HTTPS does three jobs, not one

Most people only know the first one. All three matter.

JobWhat it meansWhat breaks without it
EncryptionNobody in between can read the data (the data is scrambled)Passwords and session cookies (small data the site uses to remember you are logged in) get stolen on public WiFi
AuthenticationYou are really talking to yourapp.com, not to a fakeSomeone sets up a fake WiFi hotspot, shows a fake login page and collects logins
IntegrityNobody changed the data on the wayA network adds ads to your page, or swaps a bank account number in it
Certificates are for the second job

The second job, authentication (proving who you are talking to), is what certificates are for. Encryption alone is not enough. You could encrypt your password perfectly and still send it to a criminal.

Key terms explained

TermSimple meaning
SSLSSL (Secure Sockets Layer) is the old name and the old technology. It is no longer safe or used, but people still say “SSL certificate” out of habit.
TLSTLS (Transport Layer Security) is the set of rules that encrypts (scrambles) data between a browser and a server. It is what really runs today. HTTPS means HTTP carried inside TLS.
CertificateA certificate is a digital ID card for your domain. It proves “this server really is yourapp.com”.
CA (Certificate Authority)A CA (Certificate Authority) is a trusted organisation that issues certificates. Browsers come with a built-in list of CAs they trust.
Public keyOne half of a key pair. It is shared openly inside your certificate. Anyone can use it to check a proof that only the private key could make.
Private keyThe other half of the key pair. It stays secret on your server. The server uses it to prove it owns the certificate. If it leaks, someone else can pretend to be your site.
Let's EncryptA free CA that issues browser-trusted certificates automatically, at no cost.
AWS ACMAWS Certificate Manager. A service that gives you certificates. Public certificates are free and renew by themselves when used with AWS services like ALB and CloudFront.

The chain of trust

Your browser has never heard of yourapp.com. So why does it trust it?

Think of a passport

A border officer in another country does not know you. But they trust the Indian government, and the Indian government gave you a passport that says who you are. Trust comes from an authority that both sides already accept.

Certificates work the same way. Every browser and operating system comes with a built-in list of Root Certificate Authorities (the top-level CAs) that it trusts. The list has more than 100 root certificates. A root CA signs an intermediate certificate. The intermediate signs yours. This is the chain.

  1. Root CA
    pre-installed in every browser and OS
  2. signs
    Intermediate CA
    signed by the root
  3. signs
    Your certificate
    yourapp.com
The chain of trust. Your server sends its certificate plus the intermediate, so the browser can walk the chain up to a root it already trusts. Trust the root, trust everything signed below it.

If any link in the chain is missing, expired, or signed by someone the browser does not know, you see the red warning page.

The handshake, step by step

The handshake is the short opening talk between browser and server. It takes milliseconds. It happens once per connection, before your page starts to load.

  1. Browser says hello

    It connects and says “I want to use TLS. Here are the encryption methods I support.”

  2. Server sends its certificate

    It also sends the intermediate certificates (the chain), and picks one of the encryption methods the browser offered.

  3. Browser verifies the certificate

    It makes three checks. Is it signed by a trusted CA? Is today's date inside its valid dates? Does the domain name on it match the site I typed?

  4. Both sides agree a shared key

    A key exchange is a way for two sides to create the same secret key without sending it over the network. Both sides now have a shared secret key. Nobody who watched the talk can work it out.

  5. Everything after this is encrypted

    All page content, form data and API calls now travel inside the encrypted connection (the “tunnel”).

Step 3 is where all the security lives

If any of the three checks fails, the browser stops and shows a warning instead of your site.

step 1 / 9
Before TLS
TCP connection opens on port 443

DNS already turned yourapp.com into 52.66.12.9 (Lesson 3). The browser opens a plain TCP connection to port 443. Nothing is encrypted yet — TLS has not started.

Browser
wantsyourapp.com
connected to52.66.12.9:443
(nothing on the wire)
Server · 52.66.12.9
listening on:443
hascertificate + private key
👀 Someone on the same Wi-Fi seesa connection from you to 52.66.12.9, port 443
Step through the handshake. Watch both sides end up with the same session key without it ever being sent, the certificate get checked, and the eavesdropper's view go from readable to useless. · interactive

Two ways to get a free certificate

AWS ACMLet's Encrypt (Certbot)
CostFreeFree
RenewalAutomatic, no work from you (for certificates used with AWS services)Certificates last 90 days. A timer renews them automatically
Works on raw EC2 + NginxNoYes
Works with ALB / CloudFrontYesNot needed there
When you will use itLesson 12 onward, once you have a Load BalancerLesson 7, your first EC2 deploy
The key limitation

The normal free ACM certificate cannot be installed on a plain EC2 server. AWS never gives you its private key. It works only when attached to an AWS service that ends (terminates) TLS for you, such as ALB, CloudFront or API Gateway. (Since 2025, ACM also sells “exportable” certificates that you can put on any server, but they are paid, so they are not part of this course.) For your first single-server deployment, Let's Encrypt is the answer.

Real example — HTTPS on your EC2 server

Two things must already be true before you start

This is where Lessons 2 and 3 connect:

  1. yourapp.com DNS must already point to your EC2's IP — verify with dig yourapp.com +short
  2. Port 80 must be open in your Security Group. Let's Encrypt checks that you own the domain by fetching a small file from your server over port 80

If either one is wrong, Certbot fails. Most “certbot does not work” problems are really DNS or Security Group problems.

Certbot is a free tool that gets Let's Encrypt certificates and sets them up for you. Install it with its Nginx plugin. Then ask for a certificate that covers both the bare name and the www name:

On the EC2 server
  • sudo apt install certbot python3-certbot-nginx -y

    Install Certbot with the Nginx plugin

  • sudo certbot --nginx -d yourapp.com -d www.yourapp.com

    Request the certificate. Certbot asks for an email (for expiry warnings), proves you own the domain, then edits your Nginx config.

Certbot also sets up a timer that renews the certificate before its 90 days end. You do not need to touch it. But test it once with sudo certbot renew --dry-run, so you are not surprised in three months. (Let's Encrypt plans shorter lifetimes in the future. The timer handles that too.)

That is genuinely it

Certbot writes the certificate paths into your Nginx config and adds the HTTP-to-HTTPS redirect for you.

The Nginx config afterward

/etc/nginx/sites-available/yourapp.com — the parts Certbot adds
server {
    listen 443 ssl;
    ssl_certificate     /etc/letsencrypt/live/yourapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourapp.com/privkey.pem;
    # ...your existing location / { proxy_pass ... } stays as it was
}

server {
    listen 80;                                  # plain HTTP
    return 301 https://$host$request_uri;       # push everyone to HTTPS
}

Look at fullchain.pem. This file holds your certificate plus the intermediate certificate. That is the chain from the diagram above.

privkey.pem is your private key

If that file leaks, someone else can pretend to be your site. You must revoke the certificate (cancel it) and get a new one. Only root should be able to read it. This goes back to the file permissions in Lesson 1.

Common errors you will actually hit

ErrorCauseFix
ERR_CERT_COMMON_NAME_INVALIDThe certificate covers yourapp.com, but you visited www.yourapp.comGet a new certificate with both names: -d yourapp.com -d www.yourapp.com
ERR_CERT_DATE_INVALIDThe certificate has expiredRun sudo certbot renew, then find out why the timer did not run
Mixed content warningThe page loads over HTTPS but asks for an image or script over http://Use relative paths (/logo.png) or https:// for everything
ERR_TOO_MANY_REDIRECTSThe load balancer already handles TLS, but Nginx also redirects to HTTPS. This makes an endless loopCheck the X-Forwarded-Proto header (it tells Nginx if the user came in with http or https) instead of $scheme
Certbot “challenge failed”DNS does not point to the server yet, or port 80 is closedCheck DNS with dig and fix it. Open port 80 in the Security Group

Mixed content is the most common problem when you first move to HTTPS. The page loads, but some images quietly disappear, and the padlock shows a warning instead of a clean lock.

Verifying it yourself

From any machine
  • curl -I http://yourapp.com

    Should return 301 Moved Permanently and a Location header with the https:// address

In the browser, click the padlock icon next to the address. It shows the issuer, the valid dates and the full certificate chain. It is the same information in an easier form.

What HTTPS does not do

It protects data in transit, nothing else

HTTPS protects data while it travels. It does nothing for data stored in your database. It does nothing against bad code, such as SQL injection (an attack where a user types database commands into a form). A site can have a perfect certificate and still be unsafe. These are separate problems. Lesson 18 covers them.

Cost

Let's Encrypt certificates are free. Public ACM certificates are free too, when used with AWS services such as a load balancer. The only indirect cost is the Load Balancer that ACM needs. Lesson 12 prices it properly.


Practice task before Lesson 5

You do not have a server yet, so today you look at certificates that already exist. Every command only reads data and works from your laptop.

practice.sh
curl -I http://github.com      # expect 301 and a Location: https://... header

Then open https://github.com and click the padlock: find the issuer, the expiry date and the chain. Finally visit https://expired.badssl.com and https://wrong.host.badssl.com and read the exact error each one shows.

Then answer these in your own words:

  1. Look at the three checks in handshake step 3. Which one did wrong.host.badssl.com fail? Which one did expired.badssl.com fail?
  2. Why can you not use a free ACM certificate on your first EC2 server? What will you use instead?
  3. Certbot says “challenge failed”. Name the two things from Lessons 2 and 3 that you check before you run Certbot again.
  4. Your site has a perfect padlock, but a customer's data was stolen from the database. Did HTTPS fail? Why or why not?
Optional stretch

Open chrome://settings/security → Manage certificates, and find the list of trusted root certificates. Count how many your machine trusts. Every HTTPS site you have visited was vouched for by one of them.

Conclusion

HTTPS is HTTP inside a locked box. TLS does the locking. A certificate proves whose box it is. A chain of trust back to a Root CA is why your browser believes that proof, even though it has never met your server.

  • Three jobs: encryption (nobody can read it), authentication (it really is yourapp.com) and integrity (nobody changed it). Certificates are for the second job.
  • The handshake takes milliseconds. Step 3 (trusted CA, valid dates, matching name) is where every red warning page comes from.
  • Two free sources: Let's Encrypt (Certbot) for a plain EC2 + Nginx server in Lesson 7, and ACM from Lesson 12, once an ALB or CloudFront ends TLS for you.
  • Before Certbot: DNS must point to the server and port 80 must be open. After Certbot: protect privkey.pem like the .env file from Lesson 1.
  • Not a full protection: HTTPS protects data in transit only. The database and the code are the topic of Lesson 18.

Lessons 2, 3 and 4 together show the whole path from a typed domain name to an encrypted talk with your app. Next we go back into the AWS account and set up identity properly.


End of Lesson 4. Next: Lesson 5 — AWS Account and IAM.

Before Lesson 5, read: The Pieces You Keep Hearing About → — Nginx, PM2, load balancers, RDS, VPC and every other name that Lessons 0–4 mention but do not yet explain, each with a flow diagram and a short “how”.

Published by Jainik · Last updated · How these lessons are made

Keep learning

Part of the study guide

Related series