Skip to content

How It Works

José Carrillo edited this page Jun 13, 2026 · 2 revisions

How It Works

This page explains Zefer's algorithm so that anyone can follow it — no security background required — while still giving the exact details an expert can verify. New terms link to the Glossary.

The idea in one picture

Think of a locked box. You put your secret inside, lock it with a key made from your passphrase, and hand the locked box to anyone. Only someone who can recreate the key (i.e., knows the passphrase) can open it. Crucially, the locking and unlocking happen on your own device — the box never visits a warehouse (server).

flowchart LR
  A["Your text or file"] --> B["Your browser locks it<br/>(AES-256-GCM)"]
  B --> C[(".zefer file<br/>= locked box")]
  C --> D["Share by email, chat, drive…"]
  D --> E["Recipient's browser"]
  E -->|"correct passphrase"| F["Original text or file"]
  E -->|"wrong passphrase"| G["Stays locked"]
Loading

No server ever sees your data, your passphrase, or your key. See Zero-knowledge and Client-side.

What happens when you encrypt

  1. You provide text or a file and a passphrase (minimum 6 characters). Optionally: a second passphrase, a reveal key, an expiration, a secret question, an IP allowlist, a max-attempts limit, compression, and a strength level.
  2. Key derivation. Your passphrase is turned into a 256-bit key with PBKDF2-SHA256 using a fresh random 32-byte salt and the chosen iteration count (300k / 600k / 1,000,000). This step is deliberately slow to make guessing expensive.
  3. Payload assembly. Your content is bundled with its hidden metadata (file name/type, created/expiry timestamps, hashed secret-question answer, allowed IPs, max attempts) into one payload.
  4. Encryption. The payload is sealed with AES-256-GCM using a random 12-byte IV. Large payloads are split into 16 MB chunks, each with a unique IV and a 16-byte authentication tag.
  5. Packaging into a .zefer file: a magic header (ZEFB3, or ZEFR3 with a reveal key), a small public header, the salt + IV, and the encrypted chunks.
  6. Download & share. The file is built in memory and downloaded. Share it anywhere — it is useless without the passphrase.
flowchart TD
  P["Passphrase"] --> KD["PBKDF2-SHA256<br/>+ 32-byte salt · 600k iterations"]
  KD --> K["256-bit AES key"]
  IN["Text / File + hidden metadata"] --> PL["Payload:<br/>length + metadata + content"]
  PL --> ENC["AES-256-GCM<br/>12-byte IV · 16-byte tag · 16 MB chunks"]
  K --> ENC
  ENC --> F[(".zefer file:<br/>header + salt + IV + chunks")]
Loading

What happens when you decrypt

The recipient uploads the .zefer file and types the passphrase. Their browser repeats the key derivation, verifies the tamper-proof seal, decrypts, and only then checks any access rules.

sequenceDiagram
  actor U as "You (in the browser)"
  participant Z as "Zefer (runs locally)"
  U->>Z: upload .zefer + passphrase
  Z->>Z: read public header (salt, IV, iterations)
  Z->>Z: PBKDF2 → re-derive the 256-bit key
  Z->>Z: AES-256-GCM decrypt + verify tag
  alt seal valid (right passphrase, untampered)
    Z->>Z: check expiration / IP / attempts / question
    Z-->>U: original text or file
  else seal invalid or wrong passphrase
    Z-->>U: failure — nothing is revealed
  end
Loading

If the passphrase is wrong, decryption simply fails — no hint, no partial data. If the file expired or an access rule is not met, access is denied.

Why "everything is sealed"

A common weakness in other "secure link" tools is leaving metadata (like an expiry date) in the clear, where it can be read or edited. Zefer puts all sensitive metadata inside the AES-256-GCM ciphertext. The only readable thing is the small public header. And because GCM is authenticated, any tampering is detected automatically. The full layout is on Security Architecture and Binary File Format.

Technical specifications

Property Value
Algorithm AES-256-GCM (authenticated)
Key derivation PBKDF2-SHA256
Iterations 300,000 / 600,000 / 1,000,000 (configurable)
Salt 32 bytes (256 bits), random per file
IV 12 bytes (96 bits), random; per-chunk unique
Auth tag 16 bytes per chunk
Key size 256 bits
Chunk size 16 MB
API Web Crypto API (SubtleCrypto)
Compression None / Gzip / Deflate (before encryption)
Server involvement None (100% client-side)

📖 Glossary — terms on this page: AES-256-GCM · PBKDF2 · salt · IV · authentication tag · chunk · payload · public header · zero-knowledge · client-side. Full list in the Glossary.

Clone this wiki locally