Most messaging apps ask you to trust them.
Trust that messages are encrypted in transit. Trust that logs are not kept. Trust that your account data is handled responsibly. Trust a company whose business model may not align with your privacy.
Secret Chat takes a different approach: there is nothing to trust because there is nothing to hand over.
Try it here: chat.orangely.xyz
The Core Idea
Secret Chat uses a single shared passphrase — agreed upon out-of-band — to derive both the room ID and the encryption key. Entirely in the browser. Entirely on your device.
The server never sees your passphrase. It never sees your messages. It does not know who you are. The only thing it ever touches is the encrypted ciphertext needed to route a WebRTC handshake between two peers — and even that is ephemeral.
When the session ends, nothing remains on the server.
How It Works
- Choose a passphrase. Something long and memorable — a few words you and your contact agree on privately.
- Open the app. Both users go to chat.orangely.xyz and enter the exact same passphrase.
- Keys are derived locally. The app hashes the passphrase with SHA-256 to produce a room ID and an AES-GCM encryption key. Neither ever leaves the browser.
- Peers connect. The signaling server (a Cloudflare Worker) matches the two room members and negotiates a WebRTC connection. It only sees the room ID hash — never the passphrase or key.
- ECDH fingerprint verification. After connecting, both clients exchange ephemeral ECDH public keys and display a short fingerprint in the UI. If the fingerprints match, you know there is no man-in-the-middle.
- Chat freely. Every message is AES-GCM encrypted before it leaves the browser. The relay sees only ciphertext.
- Audio calls. Click “Join Audio” to start a WebRTC peer-to-peer voice call directly between the two browsers — no third-party call infrastructure involved.
What the Server Knows
Nothing useful.
| What the server sees | What it cannot see |
|---|---|
| A hashed room ID | Your passphrase |
| Encrypted message blobs | Message content |
| WebRTC offer/answer SDP | Your identity |
| Connection timestamps | Who you are talking to |
The signaling server is implemented as a Cloudflare Worker with Durable Objects. It holds per-room WebRTC negotiation state just long enough to connect two peers, then that state is only kept for the duration of the session.
Why Not Just Use Signal?
Signal is excellent and I recommend it for most people.
Secret Chat solves a different problem: no installation, no phone number, no account.
If you need to communicate with someone who cannot or will not install an app, cannot share a phone number, or needs a session that leaves no trace in any app’s history — a browser tab that closes and disappears is a different kind of privacy guarantee.
It is also useful for short-lived coordination: one conversation, one passphrase, done.
The Technical Stack
- Frontend: React 19 + TypeScript, served as a static Cloudflare Worker asset
- Backend: Cloudflare Worker + Durable Objects for per-room signaling state
- Crypto: Web Crypto API (
SubtleCrypto) — no third-party cryptography libraries - Transport: WebRTC data channels for chat; WebRTC media tracks for audio
- Key derivation: SHA-256 passphrase hash → AES-GCM key + room ID
- Key verification: ECDH public key fingerprint exchange after peer connection
Everything runs at the edge. There is no origin server, no database, no session store.
Passphrase Strength
The app enforces a minimum passphrase length and rates strength in real time. A weak passphrase means a weak room ID and a weak encryption key, so the UI pushes you toward something like:
correct-horse-battery-staple
Or just a long sentence you can both remember. The math is simple: longer passphrase, harder to brute-force the room ID, harder to derive the key.
Who Is It For
- Journalists coordinating with sources who cannot use registered apps
- Activists or researchers who need an ephemeral channel
- People who want a private conversation without creating accounts anywhere
- Anyone who values “this conversation leaves no trace” over convenience
What Is Next
The current version covers the core loop well. Things I am considering:
- File sharing over the encrypted channel
- Multi-hop relay option for highly restrictive networks
- Passphrase-based group rooms (three or more peers)
The constraint I care most about keeping: zero server-side storage, always.
Try It
Open chat.orangely.xyz, agree on a passphrase with someone you trust, and start a conversation that the server cannot read.
No signup. No download. Close the tab when you are done.