WHAT IS WHISPER?
Whisper is an anonymous, end-to-end encrypted (E2EE) secret sharing tool. You paste a secret, get a one-time URL, and share it. The recipient opens the URL and sees the plaintext. No accounts, no tracking, no logs.
Secrets expire automatically (5 minutes to 30 days) and can optionally be destroyed after a single read (burn-after-reading). The server never sees the decryption key.
HOW DOES IT WORK?
Encryption happens entirely in your browser before anything leaves your device.
YOU (BROWSER) SERVER
───────────── ──────
plaintext
│
▼
AES-256-GCM encrypt ──ciphertext──▶ store(id, ciphertext)
+ random key (32B)
│
▼
share URL:
https://host/s/<id>#<key>
│ │
│ └── fragment: NEVER sent to server
└───────── path: server only sees the IDWhen the recipient opens the URL:
RECIPIENT (BROWSER) SERVER
─────────────────── ──────
visit URL with #fragment
│
├─── GET /api/secrets/<id> ──▶ return ciphertext
│
▼
AES-256-GCM decrypt
(key from #fragment,
never left browser)
│
▼
plaintext shown
(optionally burned on server)IS IT SAFE?
Yes, within the threat model. Whisper uses AES-256-GCM — authenticated encryption with a 256-bit key — which is the same algorithm used by banks and governments. The key never touches the server.
What you must trust: the code running in your browser. If the page itself is compromised (e.g. a supply-chain attack on the JS bundle), all bets are off. For the highest assurance, review the source and self-host.
What you do NOT need to trust: the server operator, the network, TLS certificates, or Redis storage — none of these can recover your plaintext.
WHAT DOES THE SERVER KNOW?
The server stores only:
- ciphertext — the encrypted blob (unreadable without the key)
- iv — the 12-byte initialization vector (public, needed for decryption)
- expiresAt — expiration timestamp
- burnAfterReading — boolean flag
- maxViews — optional view limit
No IP addresses are logged. No content is readable. The decryption key is never transmitted to the server.
THE URL FRAGMENT
The shareable URL has a precise structure:
https://whisper.example.com/s/AbCdEfGh#3mK9xQvZpL...
─────────────────────────── ─────────── ────────────
domain path fragment
(reaches server) secret ID base58
(server AES key
stores (browser
ciphertext) only)The #fragment (hash) portion of a URL is a browser-side concept. By HTTP specification, browsers never include the fragment in requests sent to a server. This is what makes Whisper zero-knowledge: the key physically cannot reach the server over normal HTTP.
BURN_AFTER_READING
When burn-after-reading is enabled, the server deletes the ciphertext immediately after the first successful retrieval. The secret can only be read once.
Note: "first retrieval" means the first HTTP GET that returns a 200 — not the first successful decryption. A network-level attacker who intercepts the ciphertext before the recipient could burn it. This is an inherent limitation of any server-side burn mechanism.
For extra protection, combine burn-after-reading with password protection.
PASSWORD PROTECTION
Optionally add a password when creating a secret. The random URL key (in the fragment) is used as the PBKDF2 salt; the password is the PBKDF2 input. Together they derive the AES-256-GCM encryption key (SHA-256, 600,000 iterations). The plaintext is encrypted directly with this derived key — there is no separate key-wrapping step.
The server never sees the password or derived key. The recipient must enter the correct password in their browser; it is combined with the URL key to rederive the encryption key. Share the password through a separate channel (e.g., a phone call) for maximum security.
Without the password, the URL key alone is insufficient to decrypt the secret.
TECHNICAL_SPEC
The TypeScript crypto library (@whisper/crypto) and Go implementation (internal/crypto) are cross-compatible. Both use the same AES-256-GCM algorithm, key format, and password KDF (PBKDF2-SHA-256, URL key as salt).
LIMITATIONS & TRUST MODEL
Things Whisper protects against:
- ✓ Server operator reading your secrets
- ✓ Database breaches exposing plaintext
- ✓ Network interception of the decryption key
- ✓ Passive surveillance of stored data
Things Whisper does NOT protect against:
- ✗ A compromised browser or OS on your device
- ✗ A malicious JavaScript bundle served from the host
- ✗ Screen recording or shoulder surfing
- ✗ The recipient sharing the secret after reading it
- ✗ Timing attacks to determine when a secret was accessed
For maximum trust: review the source code, verify the deployed bundle, and self-host. The architecture is intentionally simple — there is no server-side logic that could leak keys.