What you'll learn
Quick Answer
TLS gives you three things: encryption so nobody on the path can read the traffic, integrity so nobody can modify it undetected, and authentication that you are talking to the server that controls that domain name. It does not tell you the site is honest, and it does nothing once data reaches the server. The padlock means the connection is private, not that the other end deserves your data.
What TLS guarantees, and what it does not
Start with the misunderstanding that causes real harm. A padlock in the address bar does not mean a site is trustworthy. It means the connection to that site is encrypted and that the site proved it controls that domain name. Anyone who registers a domain can obtain a free certificate for it within minutes, including someone running a fake bank login page. Users have been taught to look for the padlock as a safety signal, and it is not one.
What TLS genuinely provides is three properties. Confidentiality: anyone watching the network sees ciphertext, not your request. Integrity: if a byte is altered in transit, the receiver detects it and drops the connection rather than silently accepting modified data. Authentication: the server proves, using a certificate signed by a trusted authority, that it holds the private key for that hostname.
Now the boundaries, because these are what interviews and security reviews probe. TLS protects data in transit only. The server decrypts everything on arrival, so it sees passwords in plaintext, which is exactly why you still hash passwords with bcrypt or argon2 before storing them. HTTPS does nothing about SQL injection, XSS, broken access control or a leaky API, because all of those happen after decryption.
One more limit that surprises people: even with TLS, an observer still learns which server you connected to. The hostname travels in cleartext during the handshake, and the destination IP is visible by definition. Your ISP cannot read the page you requested, but it can see the domain. Encryption hides content, not the fact of the conversation.
Certificates and certificate authorities
A certificate is a small file containing a public key, the hostnames it is valid for, a validity period, and a signature from a certificate authority. The matching private key never leaves the server. If it does, the certificate must be replaced immediately, because anyone holding that key can impersonate the site.
Trust works as a chain. Your browser and operating system ship with a store of root certificates from a few dozen authorities. Roots almost never sign server certificates directly. Instead a root signs an intermediate, and the intermediate signs your leaf certificate. Verification walks the chain upwards until it reaches a root already in the trust store.
This produces a classic deployment bug worth knowing. If you install only the leaf certificate and forget the intermediate, the site often still works in Chrome, because browsers can fetch missing intermediates on their own. It then fails in curl, in Java clients, in payment gateway callbacks and on some Android versions, which do not. The symptom is a site that looks perfectly fine to you while a partner integration reports certificate verification failures. Always install the full chain, and test with a plain client rather than a browser.
curl -vI https://example.com
openssl s_client -connect example.com:443 -servername example.com < /dev/null
# expiry dates only
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates -subject -issuerOn validation levels: domain validated certificates prove control of the domain and nothing else, and they are what free automated authorities issue. Organisation and extended validation certificates involve checks on the company, but browsers no longer display them differently in the address bar. A free DV certificate provides exactly the same encryption strength as an expensive one. Pay for a certificate when you need a warranty or a wildcard, not for stronger cryptography.
What happens during the handshake
The handshake exists to agree on one shared symmetric key without ever sending it across the network. Public key cryptography is slow, so it is used only to establish that key; everything after is encrypted with fast symmetric ciphers such as AES or ChaCha20.
The sequence, simplified but accurate in ordering:
- TCP connects first. The handshake happens on top of an already established connection.
- ClientHello: the client sends supported TLS versions, a list of cipher suites, a random value, and the hostname it wants via Server Name Indication.
- ServerHello: the server picks a version and cipher suite, sends its own random value, and sends its certificate chain.
- Key agreement: both sides run an ephemeral Diffie-Hellman exchange, typically over elliptic curves. Each side sends a public value, and each independently computes the same shared secret. The secret itself is never transmitted.
- Verification: the client checks the certificate chain against its trust store, checks the hostname matches, and checks the dates. The server proves it holds the private key by signing handshake data.
- Finished: both sides confirm with a message authenticated under the new keys. From here everything is symmetric encryption.
Two details worth carrying into an interview. First, forward secrecy: because the Diffie-Hellman keys are ephemeral and discarded after the session, an attacker who records the traffic today and steals the server's private key next year still cannot decrypt those old sessions. That is why ephemeral key exchange is now mandatory in modern TLS.
Second, SNI is sent in the clear. The client must say which hostname it wants before the server can present the right certificate, and at that moment nothing is encrypted yet. So on a shared IP hosting many sites, an observer still learns which one you asked for. Encrypted Client Hello exists to close this gap but is not universally deployed, so treat the hostname as visible.
Why HTTPS matters even with no login form
The old advice was that HTTPS is for pages with passwords or payments. That reasoning is wrong, and integrity is the reason.
Over plain HTTP, anyone on the path can modify the response, not merely read it. Cafe and hotel Wi-Fi networks have been caught injecting advertisements into pages. The severe version is script injection: if an attacker can modify one JavaScript file your page loads, they control everything the page does, including any session the user already has on that origin. A blog with no login form is still a delivery vehicle for whatever gets injected into it.
There are practical reasons too. Browsers restrict many features to secure contexts, so service workers, geolocation and camera access do not work over plain HTTP on a real domain. Localhost is treated as a secure context, which is why these features work while you develop and then break once the site is deployed over HTTP. HTTP/2 and HTTP/3 are effectively TLS-only in browsers, so staying on HTTP means giving up multiplexing. Browsers also mark plain HTTP pages with form fields as not secure, which visitors notice.
Redirecting HTTP to HTTPS is necessary but not sufficient, because the very first request still goes out unencrypted and can be intercepted before the redirect arrives. HSTS closes that window: once the browser has seen the header, it refuses to make a plaintext request to your domain at all for the stated duration.
# Nginx: redirect, then tell browsers never to try HTTP again
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;
# nginx will refuse to start on a listen ... ssl block without these
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}Be careful with includeSubDomains and with long max-age values. Once a browser has stored the policy, you cannot serve any subdomain over plain HTTP until it expires, and a staging subdomain without a certificate becomes unreachable.
Mixed content and the failures you will actually hit
You move a site to HTTPS, the padlock appears, and half the page stops working. That is mixed content: an HTTPS page loading sub-resources over HTTP.
Browsers split it in two. Active mixed content, meaning scripts, stylesheets, iframes and XHR or fetch calls, is blocked outright, because such a resource can rewrite the whole page and would destroy every guarantee TLS just provided. Passive mixed content, mainly images and media, is either blocked or auto-upgraded by modern browsers, with a warning in the console. The result is a page that renders with missing images, a broken layout and JavaScript that never runs, while the address bar still shows a padlock.
The usual culprit is hardcoded absolute URLs, very often stored in a database from before the migration, such as image paths saved by a CMS editor. Fix them at the source. As a safety net while you clean up, the browser can be told to upgrade requests automatically.
<meta http-equiv="Content-Security-Policy"
content="upgrade-insecure-requests">Avoid protocol-relative URLs like //cdn.example.com/app.js. They were a workaround from the era of mixed HTTP and HTTPS sites. Write https:// explicitly.
The other failures, in rough order of how often they bite:
- Expired certificate. The entire site becomes an interstitial warning, not a degraded experience. Automate renewal and set a calendar reminder as a backup, because renewal automation fails silently more often than people expect.
- Hostname mismatch. A certificate issued for
example.comdoes not coverwww.example.comunless both names are listed. Include every hostname you actually serve. - Wrong client clock. A device with a badly wrong date rejects valid certificates as not yet valid or expired. If one machine sees errors on every site, check its clock before blaming the server.
- Self-signed certificates. Fine on localhost where you accept the warning yourself, never acceptable in production, and never worth teaching users to click through.
