# End-to-end encrypted

> Encrypt in the browser with a passphrase. Your server and your bucket store bytes they cannot read. How to build it with s3nd, what to watch, and the full guide.

Canonical: https://www.s3nd.sh/use-cases/encrypted-sync · Markdown: https://www.s3nd.sh/use-cases/encrypted-sync.md · Français: https://www.s3nd.sh/fr/use-cases/encrypted-sync

Encrypt in the browser with a passphrase. Your server and your bucket store bytes they cannot read.

```ts
const key = await deriveKey(passphrase, salt) // PBKDF2 or Argon2, in the browser
const iv = crypto.getRandomValues(new Uint8Array(12))
const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, encoded)

// The transfer holds the salt, the IV and the ciphertext. Nothing else.
await transfers.createSnapshot({
  data: { salt: toBase64(salt), iv: toBase64(iv), ciphertext: toBase64(ciphertext) },
  version: 3,
})
```

## What is actually going on.
### The problem
By default your server can read every transfer it stores. For a journal, a password manager, health data or a contract, that is the wrong default, and a liability you may not want to hold.

### What s3nd does about it
s3nd stores whatever you hand it. Derive a key from a passphrase with WebCrypto, encrypt the payload in the browser, and send the ciphertext. The bucket, your server and anyone who guesses the code see bytes they cannot use; the passphrase travels with the person, not over the wire. The same works for a file as for a snapshot.

## The things that are easy to get wrong.
- **Compression happens after encryption** — Ciphertext does not compress. Expect the stored size to match the raw size, and set maxSize accordingly.
- **Two secrets, two channels** — The code goes over one channel and the passphrase over another, or in the person’s head. A code alone is now worth nothing to a guesser.
- **A lost passphrase is lost data** — That is what end-to-end means. Say so in the interface before the user relies on it.

Packages: @s3nd/protocol, s3nd. [End-to-end encrypted sync, in full](https://doc.s3nd.sh/docs/use-cases/encrypted-sync)
