TLS doesn’t actually wrap TCP; it sits on top of TCP, using its reliable stream to send encrypted data.
Let’s watch this in action. Imagine a simple web server and a client. Normally, the client connects to the server over TCP, and then they exchange HTTP messages.
# On the server (simplified, actual TLS setup is more involved)
openssl s_server -accept 443 -cert server.pem -key server.key
# On the client
openssl s_client -connect localhost:443
When you type GET / HTTP/1.1 into the s_client terminal and press Enter twice, you’re not sending that directly to the server. First, the s_client establishes a TCP connection to localhost:443. Then, it initiates the TLS handshake. This handshake is a negotiation: the client and server agree on encryption algorithms, exchange certificates to verify each other’s identity, and generate a shared secret key. Only after this handshake is complete does the client send your GET / HTTP/1.1 request, now encrypted using the negotiated keys. The server decrypts it, processes the request, and sends an encrypted HTTP response back, which the client then decrypts. TCP is none the wiser about the encrypted content; it just sees a stream of bytes to deliver reliably.
The core problem TLS solves is confidentiality and integrity for data in transit. Before TLS, data sent over TCP was plain text, visible to anyone sniffing the network. TLS adds a cryptographic layer that ensures:
- Confidentiality: Only the client and server can read the data.
- Integrity: The data cannot be tampered with in transit without detection.
- Authentication: The client can verify the server’s identity (and vice-versa, if configured).
Here’s how it works internally. When a TLS connection is established, the client and server go through a handshake.
- Client Hello: The client sends a message listing the TLS versions it supports, cipher suites it can use (combinations of encryption, authentication, and key exchange algorithms), and a random string.
- Server Hello: The server picks the highest TLS version and best cipher suite from the client’s list, sends its own random string, and its digital certificate.
- Authentication: The client verifies the server’s certificate against a trusted list of Certificate Authorities (CAs). If it’s valid, the client knows it’s talking to the real server.
- Key Exchange: The client and server use the information exchanged (including their random strings and the server’s certificate) to generate a symmetric session key. This is the crucial part: the heavy encryption for the actual data will use this fast, shared key, not the slower asymmetric encryption used for the handshake.
- Finished: Both sides send a "Finished" message, encrypted with the newly generated session key, confirming the handshake is complete.
From that point on, all application data (like HTTP requests/responses) is encrypted and decrypted using the symmetric session key. TCP just faithfully transmits these encrypted byte streams.
The mental model is a secure tunnel through the unreliable, unencrypted TCP pipe. TCP provides the reliable delivery mechanism, ensuring packets arrive in order and without loss. TLS uses that reliable delivery to send encrypted messages. Think of TCP as the postal service delivering letters, and TLS as the secure, locked mailbox and the special coded language used inside the letters.
The most surprising thing to many is that the vast majority of the actual data transfer in a TLS session uses symmetric encryption with a session key, not the asymmetric encryption (like RSA or Elliptic Curve Diffie-Hellman) that’s used during the handshake to securely establish that session key. The handshake is the expensive, computationally intensive part, but it’s only done once per session to agree on a shared secret. The bulk data transfer is then very fast because symmetric encryption is much more efficient.
If you dig into the handshake, you’ll find that the "cipher suite" is actually a bundle of algorithms for different purposes: one for key exchange (e.g., ECDHE), one for authentication (e.g., ECDSA or RSA), and one for bulk encryption (e.g., AES-GCM), plus a MAC algorithm (often integrated into the cipher). The server’s certificate, typically signed by a CA, is primarily used to authenticate the server’s public key during the key exchange, proving that the public key it’s using to establish the shared secret actually belongs to the legitimate server.
Once your TLS connection is humming along, the next thing you’ll likely encounter is the complexity of certificate management and revocation.