Back to selected work

E2EE Chat App

CipherChats

A real-time chat application built to work through end-to-end encryption in practice. Encryption and decryption happen in the browser; the server relays ciphertext and never holds a key that could read it.

ReactTypeScriptFastAPIWebSocketsMongoDB
CipherChats screenshot

Notes from the build

The challenge

Encryption is easy to describe and awkward to fit around a real chat. Messages arrive over a live connection, sometimes while the recipient is offline; files need to be shared without the server learning the link; and none of it means anything if a private key ever reaches the backend.

How I solved it

  • Encrypt in the browser and keep the keys in local storage, so the server only ever receives ciphertext.
  • Queue outgoing messages over the WebSocket and keep them in order, so a slow or reconnecting client does not scramble the conversation.
  • Encrypt the file link on the client before sending it; the recipient decrypts it before the download.
  • Keep history in IndexedDB so the app can reload the conversation without the server storing it.
  • Clear local messages and keys on logout, so a shared machine does not keep the readable copy.

Privacy model

Each conversation generates its own key pair. Messages are encrypted client-side before they are sent, and private keys stay in the browser. Message data is cleared on logout, and the server keeps no readable history.

How it is structured

  • React, TypeScript and Vite frontend with a FastAPI backend.
  • WebSockets for real-time delivery, with ordered message queuing for concurrent users.
  • IndexedDB with Dexie for local message storage between sessions.
  • MongoDB for accounts and conversation metadata, Google OAuth for sign-in.

File sharing

Files go to cloud storage directly; the download link is encrypted in the browser before it is sent. The recipient decrypts the link to fetch the file, so a stored link on its own is not enough to open it.

What I learned, and what it is not

This was my way of understanding how key exchange, client-side crypto, and real-time delivery fit together in one app. The cryptography is a learning implementation, not an audited one, and there is no story for rotating keys if a device is compromised.

Keep exploring

Other projects

View all work