Experimental prototype · for learning, not for real secrets
End-to-end encrypted chat, taken apart.
KootKey Chat is a small working chat app built to show how end-to-end encryption actually works. Create an identity, message another user, and watch the server relay messages it cannot read.
Everything on this page is explained in plain language first, with the technical details at the end of each section.
What “end-to-end encrypted” means
In an end-to-end encrypted (E2EE) chat, a message is locked on the sender’s device and can only be unlocked on the recipient’s device. Everything in between, including the company’s servers, only ever handles scrambled data.
Ordinary “encrypted in transit”
Most websites use HTTPS. It protects data while it travels between you and the server, but the server decrypts it and can read, store or hand over your messages.
End-to-end encrypted
The server never has the key. It stores ciphertext and nothing more, so even a hacked or compromised server cannot read your conversations.
How this prototype does it
The hardest problem is getting two people to share a secret key without ever sending that key over the network. KootKey Chat solves it with public-key cryptography. Each person has a pair of keys: a public key that anyone may see, and a private key that never leaves their control.
-
Your browser generates a key pair
When you create an identity, your browser makes your public and private keys locally. The private key is never sent anywhere.
Two P-256 elliptic-curve pairs via the browser’s Web Crypto API: one for encryption (ECDH), one for proving who you are at sign-in (ECDSA).
-
The private key goes on your USB drive or disk
The app asks where to save your key file, so you can keep it on a pen drive and plug it in only when needed. The file is locked with a passphrase, so finding it is not enough to use it.
Encrypted with AES-256-GCM under a key derived from your passphrase using PBKDF2-SHA-256 (600,000 iterations).
-
Only the public key goes to the server
The server keeps a directory of usernames and public keys. Public keys are safe to publish: they can lock a conversation, but cannot unlock it.
-
Pick a user: fetch their public key
Choosing someone from the active-users list makes your browser download their public key from the server.
-
Both of you derive the same secret, without sending it
Think of mixing paint. You and your friend each start with a shared public colour, then add your own secret colour. You swap the mixtures, add your secret again, and both end up with an identical final colour that nobody watching could recreate. Your browser does the same with maths: your private key + their public key gives the same secret as their private key + your public key.
ECDH key agreement, then HKDF-SHA-256 with a fresh random salt per message to produce a 256-bit AES key.
-
Encrypt, send, decode
Your browser scrambles the message with that secret and sends the result to the server. The recipient presses Decode, their browser rebuilds the same secret from their private key and your public key, and the text appears.
AES-256-GCM with a random 96-bit nonce. The sender and recipient IDs are authenticated, so a message that is altered or redirected fails to decrypt instead of showing garbage.
What the server can and cannot see
| The server can see | The server cannot see |
|---|---|
| Usernames and public keys | Private keys or key-file passphrases |
| Who messaged whom, and when | What any message says |
| Roughly how long each message is | The shared secret between two users |
| Which users are currently active | Your decoded messages |
The public board: public, yet unreadable
To make the idea concrete, the public board lists every message on the platform for anyone to see, signed in or not. Each one sits next to a Decode button, but only the person a message is addressed to can use it.
That is the whole point of E2EE: the ciphertext can be shown to the world because it is useless without the right private key. A visitor, another user, or the server administrator all see the same wall of scrambled text.
Notice what the board does reveal: who wrote to whom, and when. Encryption hides the content, not the fact that a conversation happened. That is called metadata, and it is a real privacy concern in actual messengers too.
Try it in five minutes
- Open the demo and create an identity. Save the key file to a USB drive or a folder.
- In a private window or a second browser, create a second identity (Chrome or Edge give the best file-picker experience).
- From one account, choose the other in the user list and send a message.
- Open the public board and look at the ciphertext. Then sign in as the recipient, load the key file, and press Decode.
- Try the Decode button as the sender or as a third user. It stays disabled, because no other key fits.
Honest limits: why this is only a prototype
Do not use KootKey Chat for anything sensitive. It is built to teach one idea clearly, not to protect real secrets.
No forward secrecy
Your keys are long-lived. If someone ever steals your key file and passphrase, they can read every past message addressed to you. Apps like Signal change keys with every message to prevent this.
Trusting the key directory
A dishonest server could hand you the wrong public key. KootKey Chat shows a safety number and warns you if a contact’s key changes, but you must compare that number yourself, ideally over a call.
The app itself is delivered by the server
Because this is a web page, a compromised server could serve altered code. Native apps and reproducible builds exist partly to close that gap.
Metadata is visible
The server and, on the public board, everyone can see who talks to whom and when.
No recovery, one device
Lose the key file or passphrase and the account and its messages are gone for good. There is no multi-device sync and no password reset.
Simplified features
No group chats, attachments, read-receipt privacy, disappearing messages or abuse controls, and only basic rate limiting.
What production messengers add
Real systems build on the same core idea but add the Double Ratchet algorithm for forward secrecy, authenticated key verification, secure multi-device support, independent security audits, and years of hardening. KootKey Chat deliberately leaves these out so the core mechanism stays readable.
Technical summary
| Purpose | Technique |
|---|---|
| Key generation | ECDH and ECDSA on curve P-256, in the browser (Web Crypto API) |
| Key file protection | PBKDF2-SHA-256 (600,000 rounds) + AES-256-GCM |
| Shared secret | ECDH(own private, peer public), then HKDF-SHA-256 with a random salt per message |
| Message encryption | AES-256-GCM, random 96-bit nonce, sender and recipient bound as authenticated data |
| Sign-in | Challenge–response: the browser signs a one-time server nonce, so no password is sent |
| Backend | PHP and MySQL. Stores public keys and ciphertext only |
| Frontend | Plain JavaScript, no libraries |
Questions people ask
Can the site administrator read my messages?
No. The administrator can see the database, but it contains only public keys and ciphertext. Without your private key, the messages cannot be opened. The administrator can see who messaged whom and when.
Why do I have to pick my key file again to decode?
The private key lives on your USB drive or disk, not on the server and not in the browser’s storage. When you send or decode, the app loads it into memory, uses it, and locks it again after 10 idle minutes or when you press Lock.
Can the sender read a message after sending it?
Yes, in the chat view. The shared secret is the same for both people, so the sender’s own private key plus the recipient’s public key reopens it. The public board only decodes messages addressed to you.
What if I lose my key file?
It cannot be recovered. That is the trade-off of a system where only you hold the key: nobody can reset it for you.
See it for yourself
Create two accounts or create one account for yourself and ask your family member or friend to create another account , send a message, and compare what you see on the public board with what the recipient sees after decoding.