A year ago I wrote a series of articles about how a web server works.
I started from a very primitive version and step by step moved toward the same core ideas modern production servers rely on. That journey was already deep enough on its own. But when I finished it, I had one more thing in mind.
A small improvement.
Wrap the server in TLS. Make the communication secure.
At least, that was how it looked from the outside.
In reality, that “small improvement” turned into a much longer journey than I expected. What looked like one tiny feature hidden behind the familiar lock icon in the browser opened the door into a huge world of cryptography, key exchange, authentication, certificates, trust, protocol design, and many layers of details that usually stay invisible when everything just works.
And that is exactly why I decided to make this series.
I did not want to approach TLS as a finished black box. I did not want to start from the RFC and just repeat the names of the protocol messages until they sounded familiar. I wanted to understand what TLS is, why it exists in the form it exists, and why it needs so many moving parts.
So this series is my attempt to rebuild it.
Not the full production-ready TLS implementation, of course. But a step-by-step reconstruction of the logic behind it. We will start from something intentionally naive, something that only looks secure, and in each article we will add one missing piece, one new idea, one more reason why real TLS had to become what it is.
By the end, I want us to arrive at a simplified TLS-like protocol that is close enough to the real thing to make the real thing much easier to understand.
Because that is still the real goal.
The point of the toy protocol is to make real TLS easier to understand. The completed series follows that path through record protection, key exchange, certificates, and trust. The repository and Part 4 walkthrough linked below let you inspect the final implementation and its simplifications.
But I really believe that jumping directly into the finished TLS protocol is the wrong way to learn it.
TLS is one of those technologies where the final design hides the reasons. If you look at the real protocol too early, you see a forest of details: handshakes, certificates, transcript hashes, traffic secrets, record protection, extensions, verification steps. All of them are there for a reason. But those reasons are much easier to understand when you first build the broken versions that fail without them.
That is the main idea of this series:
we will learn TLS by first building the wrong thing, and then fixing it step by step.
So if your goal is to understand the real TLS better, I would strongly recommend following the whole journey and not jumping directly to the last part.
As I mentioned, TLS is built on many cryptographic ideas. I will explain the important ones when we need them, but I also already wrote a separate series where I rebuild the main cryptographic foundations from scratch:
So throughout this TLS series, I will link back to those parts whenever we meet a concept that deserves a deeper look.
This page is the central hub for the completed series. It brings the articles, code, and walkthrough together in one reading path.
I really hope you enjoy this journey as much as I do.
Full Summary of the TLS Series
Status: complete. Read Parts 1–5 in order, from encryption and record integrity to the handshake, certificates, and trust. And adding toy-TLS to the toy-WebServer in the end.
Rebuilding TLS, Part 1 — Why Encryption Alone Is Not Enough
From transparent TCP traffic to encrypted records — and the first reason TLS needs more than encryption
Rebuilding TLS, Part 2 — Adding Integrity to the Channel
We teach our protocol to detect tampering, make records less naive with sequence numbers, and then switch to the AEAD style used in real systems.
Rebuilding TLS, Part 3 — Building Our First Handshake
We get rid of the pre-shared key assumption, build a simple key exchange handshake, and discover why key agreement alone still does not give us real TLS.
Rebuilding TLS, Part 4 - Certificates and Trust
We add certificates and a certificate authority to authenticate the server, explain how verification helps prevent man-in-the-middle attacks, and integrate this final piece into our simplified TLS protocol.
Adding Homemade TLS to a Homemade Web Server
This article connects two series. In the web-server series, I rebuilt the HTTP side from raw sockets up to routing and file serving. In the current TLS series, I rebuilt the secure-channel side: key exchange, certificates, key derivation, and encrypted records.
This piece is where the two meet: what has to change when a web server stops receiving plaintext HTTP bytes and starts receiving encrypted TCP bytes?
What this series is really about
This is not just a series about TLS.
It is also another exercise in the same thing I keep coming back to again and again: taking foundational technology that usually appears to us as a finished black box, opening it up, and rebuilding it from simpler parts until it stops feeling magical.
That was the idea behind the web server series.
That was the idea behind the cryptography series.
And now this is the same idea applied to TLS.
Follow the journey
This page will stay the central entry point for the whole series.
If you enjoyed rebuilding TLS, continue with the networking series, which follows the machinery beneath a socket, from Ethernet and IP toward Linux and the power grid. Subscribe to Rebuilt to follow the next system as I rebuild it.
Links
Part 4 walkthrough (rendered) — dmytrohuzz.github.io/rebuilding_tls/.../walkthrough.html
Repository — github.com/DmytroHuzz/rebuilding_tls
Questions, feedback, found a bug? — LinkedIn: dmitriyhuz










Inspired to learn more about TLS!
It’s already TLS 1.3 for ~10 years, but we are still on TLS 1.2. Besides TLS 1.2 is a bulletproof with a right configuration in anyway.
Hope it should give me a motivation to revisit the current configs. 🙂
Looking forward to dive into reading!