How this clipboard's end-to-end encryption works
A plain account of what is encrypted, with what, and what this design does and does not defend against. There is no hand-waving here: browser-based end-to-end encryption has a hard ceiling, and it is named further down the page rather than buried.
- Native WebCrypto only
- No plaintext on the server
- Limits stated
Try it
Enters automatically once all six digits are in
Content is encrypted in your browser before upload — the server never sees plaintext. Destroyed after 24 hours of inactivity.
The key exchange, step by step
Five steps run between the two browsers. The server relays the messages and can read none of them.
The creator's browser generates a content key
A 256-bit AES key, produced by WebCrypto and written to localStorage. This key is the only thing that can decrypt anything in the clipboard, and the server never holds it.
Every item is encrypted before it is uploaded
Each entry is sealed with AES-256-GCM under a fresh IV. What reaches the server is a pair of {iv, ciphertext} — there is no code path that sends plaintext.
A guest generates an ephemeral keypair
When someone enters the 6-digit code, their browser creates a one-time ECDH P-256 keypair and sends the public half with the join request. The private half stays on their device.
Approval performs the exchange
When the creator approves, their browser runs ECDH against the guest's public key, derives a one-time wrapping key with HKDF-SHA-256, encrypts the content key under it, and hands the wrapped blob to the server for relay.
The guest unwraps it
Their browser derives the same wrapping key from its own private key, opens the blob and recovers the content key. If it fails to open, the exchange was tampered with in transit and the guest is not let in.
The cryptography
Everything uses the browser's native WebCrypto. There is no third-party cryptography library in the bundle.
- Content encryption
- AES-256-GCM, with a fresh random 96-bit IV for every item
- Key agreement
- ECDH on P-256. Not X25519 — Safari still does not support it in WebCrypto
- Key derivation
- HKDF-SHA-256, info = clipboard/cek-wrap/v1
- Where the content key lives
- localStorage on the approved devices. It is never transmitted to the server in a form the server can open
- What the server receives
- A 6-digit code, hashed tokens, two public keys, one wrapped key and ciphertext blobs
- Confirmation code
- 4 characters derived from the guest's public key, shown on both screens
- Retention
- The whole clipboard is destroyed 24 hours after the last write
What this design protects against
Server-side logs
Nothing readable passes through request logging, because nothing readable is sent.
Database and Redis dumps
A full dump of the store yields codes, hashes, public keys and ciphertext. None of it decrypts without a key that only exists on two devices.
Backup snapshots
Backups inherit the same property. An old snapshot is as useless as a fresh one.
A later breach
Someone who gets into the infrastructure next month finds ciphertext for anything not already expired — and almost everything will have expired.
Guessing a code
Entering a valid 6-digit code creates a visible join request and nothing more. No content key is issued until a human approves it.
A tampered key exchange
GCM authenticates the wrapped key. If it was altered in flight, unwrapping fails and the guest is refused rather than silently handed a substituted key.
What it does not protect against
The page doing the encrypting is JavaScript delivered by the server. A server that wanted your plaintext could serve a modified page that quietly sends it, and no client-side cryptography can stop that — the cryptography is part of the payload being served. This is the shared ceiling of every in-browser end-to-end encrypted product, and it is worth knowing rather than glossing over. What the design does buy is everything after the fact: logs, dumps, backups and future breaches all come up empty.
Metadata stays visible. The server knows a clipboard exists, how many items it holds, roughly how large each one is, when each arrived and from which IP address. It does not know what any of them say.
And losing the key means losing the content. The content key exists only in localStorage on the approved devices. Clear site data and that clipboard is permanently unreadable — there is no recovery path, on purpose, because a recovery path is a copy of the key somewhere else.
Why the confirmation code is only four characters
Both screens show a 4-character code derived from the guest's public key. Its primary job is mundane: when several people request access at once, it tells you which request belongs to which person. Secondarily, it makes a clumsy key substitution visible — a relay that swapped in its own public key would produce a different code on the two screens.
It is deliberately short, and lengthening it would be theatre. Against a server that can serve a backdoored page, a longer code protects nothing, because the same server also renders the code you are comparing. An honest four characters that people actually check beats twelve that nobody reads.
Verifying it yourself
You do not have to take any of this on faith for the parts that are observable. Open your browser's developer tools, watch the network tab, and paste an item: the request body contains an IV and a ciphertext blob, and the text you typed appears nowhere in it. The same holds for the join and approval requests, which carry public keys and a wrapped blob.
What that check cannot prove is what a future version of the page would do — which is precisely the limit described above.
Security questions
Is an online clipboard safe?
The question that matters is whether the operator can read what you paste. Most online clipboards can. This one cannot read the content, because encryption happens in your browser and the key never reaches the server. The residual risk is a malicious server serving a backdoored page, which applies to every browser-based end-to-end tool.
Can the server read my content?
Not as it is built. The server receives {iv, ciphertext} pairs and has no key to open them. It also never sees the content key — that is transferred encrypted between the two browsers.
What algorithms are used?
AES-256-GCM for content, ECDH on P-256 for key agreement, and HKDF-SHA-256 to derive the one-time wrapping key. All of it runs on the browser's native WebCrypto implementation.
Why P-256 instead of X25519?
Safari's WebCrypto still does not support X25519. P-256 is supported everywhere and is entirely adequate here; the choice is about compatibility, not preference.
Can somebody brute-force a 6-digit code?
They can find a valid code, and it gets them a place in an approval queue. It does not get them the content key, which is only issued after a human approves the specific request.
What happens if I clear my browser data?
That clipboard becomes permanently unreadable. The content key lived only in localStorage, and no copy exists on the server. Export anything you need before clearing site data.
Is anything stored after 24 hours?
No. The clipboard and every item in it are destroyed 24 hours after the last write. Activity resets the timer; inactivity ends it.
How is this different from a service that says it uses TLS?
TLS protects data between your browser and the server. It gives the server the plaintext at the other end — which is the entire point of TLS. End-to-end encryption means the server never has plaintext to begin with, so TLS and this are complements, not alternatives.
Keep reading
- Phone ↔ computeriPhone to Windows, Android to Mac — any pair, in a browser.
- Share a passwordHand over a credential without leaving it in a chat log.
Ready when you are
Create a clipboard, read the six digits to the other side, approve, and paste.