">

How it works

The short version: your passphrase never leaves your device, and every key that could open your photos is derived from it. What we hold is unreadable to us.

The scheme, exactly

kek        = PBKDF2-HMAC-SHA256(passphrase, salt || "photosafe-kek-v1",  600000, 32 bytes)
auth_hash  = PBKDF2-HMAC-SHA256(passphrase, salt || "photosafe-auth-v1", 600000, 32 bytes)
master_key = 32 random bytes, generated once, in your browser
wrapped_mk = nonce(12) || AES-256-GCM(kek, master_key)      <- this is what we store

per photo:
file_key   = 32 random bytes
ciphertext = nonce(12) || AES-256-GCM(file_key, photo)      <- this is what we store
wrapped_fk = nonce(12) || AES-256-GCM(master_key, file_key) <- this is what we store
meta_blob  = nonce(12) || AES-256-GCM(master_key, filename+date+type)

The browser implementation is /static/js/crypto.js; the identical Python implementation is crypto_core.py. Both are short enough to read in full, and you should, because a security claim you cannot check is a marketing claim.

What we can see anyway — the honest list

End-to-end encryption hides content. It does not hide everything, and any service that tells you it does is lying. We can see:

  • Your e-mail address, and when you sign in.
  • How many objects you store, each one's encrypted size, and when it arrived.
  • The SHA-256 of each file's plaintext, which your device sends so that we can avoid storing a duplicate twice. If someone already knows a specific file exists, that hash would confirm you hold it. You can turn deduplication off in the CLI; the web uploader will get the same switch before launch.
  • Your IP address at the moment of a request, as every web server does.

We cannot see: filenames, dates, album names, image contents, thumbnails, or anything derived from them.

Where the bytes live

During the beta, ciphertext is stored on a Hetzner Storage Box in Germany — one physical location, not a multi-region object store — with Cloudflare R2 wired in as the overflow and available as a second copy. Either way the server only ever sees ciphertext: which backend a given file landed on makes no difference to what we can read, which is nothing. The metadata index is a small database on our own server; every object also carries an encrypted sidecar on every configured backend holding everything needed to rebuild that index, so losing the database — or losing one backend outright — does not lose your library.

Durability, honestly

A Storage Box is not raided across data centres the way R2 or Hetzner Object Storage are. What protects you against it:

  • The box itself is RAID-protected hardware with Hetzner's own snapshot feature (up to 10 point-in-time snapshots on our tier) — we are turning this on as a standing safety net, not a promise of geographic redundancy.
  • Every file's encrypted metadata sidecar is written to every configured backend, so a single backend going dark does not erase the index even if it does temporarily block a restore of files that only lived there.
  • The free, unthrottled export is the real safety net: it is the complete, offline-restorable copy of your library, and it costs you nothing to keep your own.
  • A genuine two-copy setup — every file written to the Storage Box and R2 — is possible with this architecture and is a real cost trade-off (roughly double the storage bill) we have not turned on for the free beta. If you want it before launch, ask.

Compared with the alternatives

ServiceWho can read your photosOpen source clientExport
Google Photos / iCloud PhotosThe provider (iCloud only with Advanced Data Protection enabled, which is off by default)NoTakeout / manual, bulk and slow
Amazon Photos, Dropbox, pCloud (standard)The providerNoYes, manual
Ente PhotosOnly youYesYes, desktop app
Immich (self-hosted)Only you — because it is your serverYesYes, it is your disk
PhotoSafeOnly youYes — the client is on this siteOne button, plus an offline restore script

We are not the only honest option here, and we will not pretend to be. Ente is a mature, audited, end-to-end encrypted product with real mobile apps, and if you need an iPhone app today you should use it. Immich is free if you are willing to run a server. PhotoSafe's case is a flat price, a format you can read without us, and an export that is a first-class feature rather than a retention obstacle.

The network is a separate layer

PhotoSafe encrypts your photos on your device before upload. It does not hide your IP address or protect the rest of your traffic on public Wi-Fi; a VPN is a different tool for that job. One option is NordVPN. A VPN does not make PhotoSafe’s encryption stronger or weaker, and we have not audited NordVPN.

Affiliate disclosure: this is an affiliate link. If you sign up through it we may earn a commission at no extra cost to you. It is a separate company’s product, not part of PhotoSafe.

What we have not done

  • No third-party security audit. When one happens we will publish it, including what it found.
  • No formal threat model for a malicious server pushing bad JavaScript to your browser — a real limit of every web-delivered E2EE app, ours included. The CLI avoids it: it is a file you can read and pin.