Skip to content
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after any top-up. Until Nov 30.

How it works

What Is TLS? How HTTPS Protects Traffic

TLS 1.3 gives HTTPS confidentiality, integrity and server authentication. Learn the handshake, certificate chains and what the padlock does not prove.

Beginner11 min readBy NotHoly

The short answer

TLS (Transport Layer Security) is a protocol that wraps a network connection in encryption. HTTPS is ordinary HTTP sent through a TLS connection. When your browser shows a padlock, it has done three things. It encrypted the data. It checked that nobody changed the data in transit. And it checked that the server proved it holds a certificate trusted for the name you typed.

The third point is the one people misread. HTTPS tells you which server you are talking to. It says nothing about whether that server is trustworthy, honest or well run.

Why plain HTTP is not enough

In How HTTP works, requests and responses are text messages, and HTTP does nothing to hide them. Every device between you and the server can read them: your home router, the access point in a café, your internet provider and the networks in between.

A passive observer can read a login form sent over plain HTTP. An active attacker on the path can do more. It can change a page before it reaches you, insert a script, or replace a download with a modified file. TLS is designed to stop both threats. It also gives the client a way to check who is answering, which plain HTTP never does.

What TLS 1.3 provides

The current version is TLS 1.3, defined in RFC 8446. TLS 1.0 and 1.1 are deprecated, as RFC 8996 explains, and TLS 1.2 is still widely deployed. Version 1.3 removed many older options, so there are fewer ways to configure the handshake badly.

TLS 1.3 gives you three properties.

Confidentiality

Application data is encrypted with session keys that only the two endpoints hold. An observer sees ciphertext. The size and timing of the traffic stay visible, but the content does not.

A full TLS 1.3 handshake uses an ephemeral key exchange. Both sides create temporary key values for the session and discard them afterward. This gives forward secrecy: if the server's certificate private key leaks years later, recorded old sessions should still be unreadable. A leaked key still lets an attacker impersonate the server from that point on, so forward secrecy protects the past, not the future.

Integrity

Each record carries an authentication tag from an AEAD cipher, such as AES-GCM or ChaCha20-Poly1305. TLS 1.3 allows only this kind of cipher. If an attacker flips a bit in transit, the tag check fails and the record is rejected.

Server authentication

The server proves that it holds the private key matching its certificate. The certificate binds that public key to a name such as example.com. The client checks the certificate and the chain of trust behind it, then checks the name. Most of the rest of this article is about that part.

The handshake, step by step

The handshake agrees on keys and proves identity before any HTTP data moves. In TLS 1.3 the usual handshake takes one round trip. The steps below follow RFC 8446 at a high level.

Step 1: the ClientHello

Your client sends a ClientHello. It lists the TLS versions and cipher suites it supports, and it includes a key share, the client's temporary public value for the key exchange. It also carries the server name indication (SNI), the host name you asked for, in plain text. Servers that host many sites need that name to pick the right certificate.

Step 2: the ServerHello

The server selects a version and cipher suite and sends its own key share. Each side combines its private value with the other side's public value and derives the same shared secret. An observer who saw both public values cannot compute that secret. From here on, the handshake is encrypted.

Step 3: the certificate and the proof

The server sends its certificate. In TLS 1.2 the certificate was visible on the wire. In TLS 1.3 it travels inside the encrypted part of the handshake.

The server then sends a CertificateVerify message, a signature over the handshake transcript made with the certificate's private key. This proves the server holds the key during this handshake. A copied certificate alone is useless to an attacker. A Finished message, a MAC over the transcript, closes the server's part.

Step 4: the client checks and finishes

Your client checks the certificate chain, the validity dates, the name in the certificate against the host you requested, and the CertificateVerify signature. If every check passes, the client sends its own Finished message, and application data can flow.

If a check fails, the client stops. A browser shows a certificate warning, and curl exits with an error. Those messages are the most useful part of TLS for a beginner, because they name the check that failed.

Certificates and chains of trust

A certificate is an X.509 structure, and RFC 5280 defines the profile used on the internet. The fields that matter most here are these.

Field What it says
Subject The entity the certificate names. For web certificates it often repeats the host name.
Subject Alternative Name (SAN) The names the certificate covers, such as example.com or *.example.com. Clients match the requested host against this list.
Issuer The certificate authority (CA) that signed this certificate.
Validity The notBefore and notAfter dates. Outside this window the certificate is not valid.
Basic Constraints Whether this certificate may sign other certificates. CA certificates are marked this way.

Modern clients ignore the Common Name (CN) in the subject for host-name checks and use the SAN list instead. A reader who looks only at the CN can misjudge a certificate.

How the chain is checked

A server rarely presents a certificate that the client can verify directly. Usually the leaf certificate, which covers the host name, is signed by an intermediate CA, and the intermediate is signed by a root CA. The client trusts a set of roots that comes with the operating system or the browser.

The client builds a path from the leaf to a trusted root. At each link it verifies the signature, checks the validity dates, and confirms that the issuer is allowed to sign certificates. Then it checks the host name. Both checks must pass.

Any trusted root can, in principle, issue a certificate for any name. Trust therefore depends on the practices of the authorities in the store. That is why vendors remove authorities that misissue certificates.

Revocation

A certificate can be revoked before it expires, for example after its key is compromised. Clients can check revocation through certificate revocation lists (CRLs) or OCSP, but these checks behave unevenly. A clean connection does not prove that a certificate was never revoked.

What TLS does not protect

The server

TLS authenticates the server's identity. It does not evaluate the server's behavior. A phishing site can obtain a valid certificate for a look-alike domain it controls. The padlock then shows that the connection reaches the holder of that domain's key, not that the domain belongs to your bank. Read the host name in the address bar before you trust the page. A correctly certified server can still be hacked or badly run.

Metadata

TLS hides content, not every fact about the connection. Anyone on the path can still see the IP addresses at each end, the port, the approximate size and timing of traffic, and the server name in the ClientHello, because SNI is sent in plain text. Encrypted Client Hello is an IETF effort to hide SNI, but check how widely it is deployed before you assume a site uses it. DNS lookups are a separate protocol and reveal the names you resolve unless you use encrypted DNS.

The endpoints

TLS protects data while it moves between two endpoints. It does not protect the endpoints. Malware on your computer can read decrypted data, and a browser extension can read every page you open. A company can also install its own trusted root on your machine and decrypt your HTTPS traffic through an inspection proxy. The client then works exactly as configured, and the trust decision belongs to whoever controls the root store.

Hands-on lab: inspect HTTPS to example.com

example.com is one of the names IANA reserves for documentation and examples. Every command below connects only to example.com. The lab changes nothing on the server and needs no account. You need a terminal with curl and openssl. The openssl commands were run with OpenSSL 3.2.4.

Your output will differ from the output shown here. IP addresses change, certificates get renewed, and dates move forward.

Step 1: read the exchange with curl

bash
curl -vI https://example.com

The -v flag prints connection details, and -I sends a HEAD request, which asks for headers only. On the machine used for this article (Windows 11 with Git Bash, curl 8.12.1, run on November 8, 2026), the relevant lines looked like this:

text
* Host example.com:443 was resolved.
* IPv4: 172.66.147.243, 104.20.23.154
* Connected to example.com (172.66.147.243) port 443
* using HTTP/1.x
> HEAD / HTTP/1.1
> Host: example.com
< HTTP/1.1 200 OK

This curl build uses Schannel, the Windows TLS library, and its verbose output differs from curl built with OpenSSL. Here curl did not print the TLS version, cipher or certificate lines this lab asks for. On an OpenSSL-based curl, look for the line naming the TLS version and cipher, and the certificate block with subject, issuer and expiry date. The next steps get the same facts from openssl.

The 200 OK means the server answered inside the TLS connection. The headers travel encrypted, and curl decrypts them locally.

Step 2: get a short summary with openssl

bash
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null

Output:

text
Connecting to 172.66.147.243
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=example.com
Hash used: SHA256
Signature type: ECDSA
Verification: OK
Server Temp Key: X25519, 253 bits
DONE

Read it line by line:

  • Protocol version: the TLS version negotiated for this connection.
  • Ciphersuite: AES-256-GCM protects the records, and SHA-384 is used in the key schedule.
  • Signature type: ECDSA, the algorithm of the certificate's key.
  • Verification: OK, meaning the chain validated against this openssl build's trust store.
  • Server Temp Key: X25519, the ephemeral key exchange that provides forward secrecy.

The -servername flag sets SNI. Without it, a server hosting several sites may return a default certificate that does not match the name you wanted. The </dev/null redirect closes standard input so the command exits.

Step 3: read the certificate fields

bash
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates

Output:

text
subject=CN=example.com
issuer=C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
notBefore=Sep 26 22:49:11 2026 GMT
notAfter=Dec 25 22:56:35 2026 GMT

The subject holds only a CN. The issuer is an intermediate CA, not a root. The validity window was open on the day of the lab and closes on December 25, 2026. Compare notAfter with the date on your own system, because an expired certificate fails even when its chain is sound.

The subject does not list the covered names, so ask for the SAN list:

bash
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -ext subjectAltName

Output:

text
X509v3 Subject Alternative Name:
    DNS:example.com, DNS:*.example.com

The wildcard covers names such as www.example.com. The client compares this list with the host in your URL.

Step 4: list the chain the server sent

bash
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | grep -E '^ *[0-9] s:|^ *i:'

Output:

text
 0 s:CN=example.com
   i:C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
 1 s:C=US, O=SSL Corporation, CN=Cloudflare TLS Issuing ECC CA 3
   i:C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
 2 s:C=US, O=SSL Corporation, CN=SSL.com TLS Transit ECC CA R2
   i:C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
 3 s:C=US, O=SSL Corporation, CN=SSL.com TLS ECC Root CA 2022
   i:C=GB, ST=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services

Each s: line is a subject and each i: line is its issuer. Entry 0 is the leaf, and each entry is issued by the one after it. Certificates can be cross-signed, so a chain may reach a root by more than one path. The client needs one valid path that ends at a root in its own store.

Step 5: confirm that the chain verifies

bash
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | grep 'Verify return code'

Output:

text
Verify return code: 0 (ok)

Zero means this openssl build's trust store accepted the chain. Other values name a specific failure, such as an expired certificate.

Step 6: make the name check fail on purpose

bash
openssl s_client -connect example.com:443 -servername example.com -verify_hostname example.org -brief </dev/null

Output, trimmed:

text
depth=0 CN=example.com
verify error:num=62:hostname mismatch
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=example.com
Verification error: hostname mismatch

The command still connects only to example.com. The -verify_hostname flag asks openssl to check the certificate against example.org, which the certificate does not cover. A browser shows the same kind of failure. This check is what stops a server with a valid certificate for one domain from passing as another.

What to take from the lab

The connection negotiated TLS 1.3, and the client accepted a chain for example.com while rejecting the same certificate for example.org. Neither result says whether the company behind example.com is trustworthy. The lab shows that your client reached the holder of the key for example.com, and nothing more.

Common mistakes

  • Reading the padlock as a trust rating. It means the channel is encrypted and the certificate checked out. It does not rate the site.
  • Checking only the CN. Modern clients match the host name against the SAN list.
  • Clicking through a certificate warning. The warning means a check failed. Find out which one before you continue.
  • Adding -k or --insecure to curl to make an error disappear. That turns off the checks you just read. Use it only against a throwaway test server, never with real credentials.
  • Writing code with verification disabled, such as verify=False in a Python HTTP client. The data is still encrypted, but to whoever answered.

How to go further

Read the overview and handshake sections of RFC 8446, then skim RFC 5280 for the certificate fields. Read the Mozilla server-side TLS guide and run a configuration check against a server you operate.

The next article in this series covers public and private keys, the math behind the certificate. If the name lookup step is new, read What is DNS? first, because its result decides which address the handshake reaches.

Sources

Sources

  1. RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3
  2. RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile
  3. Mozilla: Security/Server Side TLS
  4. OpenSSL documentation: openssl-s_client
  5. RFC 8996: Deprecating TLS 1.0 and TLS 1.1
  6. IANA: Example domains

More in Networks and the web