โ† Blog

How zero-knowledge link sharing works

"Zero-knowledge" gets used for a lot of things it does not mean. For encrypted links, it means one specific thing: we store your encrypted message, but we never get our hands on the key to decrypt it. In case our database leaks or there is some other breach, an attacker gets random looking bytes, not your shared secret.

This is how Nullo does it, and how most tools in this category work.

Encrypt first, upload second

You type a password, API key, whatever. Before anything leaves your machine, the app encrypts it with industry standard AES-256-GCM. What hits the server is ciphertext that looks like random bytes.

We also store metadata the service needs to function: expiry time, view count, burn-after-read flag. That stuff is not secret, it is how we know when to delete the record.

The key goes in the fragment

The recipient needs the decryption key. For link sharing, that key goes in the URL fragment, the part after #:

https://nullo.app/s/abc123#k=BASE64URL_KEY
         โ†‘ server sees this    โ†‘ browser only

Browsers do not send the fragment to the server on HTTP requests. JavaScript on the page can read it, but it never shows up in our logs, your reverse proxy, or anything else we can see.

Decryption happens in the browser

Recipient opens the link. Our server returns the page and the ciphertext. Their browser reads the key from the fragment and decrypts the message with WebCrypto AES-GCM. Plaintext only exists in browser memory, not in our database, logs, or admin panel.

Burn-after-read is trickier than it sounds

Link previews could be a problem. Slack, iMessage, email clients, security scanners. They fetch URLs before a human clicks them. If opening the page counts as a read, your one-time secret gets burned by a bot and also potentially exposed by the preview.

We wait for an explicit "Reveal" click before consuming a burn-after-read link. A preview fetch loads the page but does not burn the secret.

What this does not give you

Zero-knowledge means we cannot read your secret. It does not mean you are anonymous. We use anonymous account numbers instead of email logins, but that is a separate topic from the encryption model.

It also does not mean you can post the link publicly. Anyone with the full URL, fragment included, can view the message until expiry or burn.