-
Notifications
You must be signed in to change notification settings - Fork 1
Security Architecture
This page describes Zefer's cryptographic design — first in plain language, then with the exact parameters an expert can verify. All cryptography uses the browser's audited Web Crypto API; Zefer ships no custom crypto. New terms link to the Glossary.
- You give a passphrase. By itself it is a weak, human key.
- Zefer runs it through a deliberately slow "key-stretching" recipe (PBKDF2) mixed with a random salt, producing a strong 256-bit key. The slowness is the point: it makes guessing millions of passphrases very expensive.
- That key locks your data with AES-256-GCM — a lock that also adds a tamper-proof seal.
- Only the locked result and a tiny, non-secret label leave your screen (as a file). The makers of Zefer never receive your key or your data.
| Purpose | Primitive | Parameters |
|---|---|---|
| Symmetric encryption | AES-256-GCM | 256-bit key, 12-byte IV, 16-byte tag |
| Key derivation | PBKDF2-SHA256 | 32-byte salt, 300k / 600k / 1,000,000 iterations |
| Secret-question answer | PBKDF2-SHA256 | hashed at 100,000 iterations |
| Randomness | crypto.getRandomValues |
salts, IVs, generated keys |
| Compression (optional) | Gzip / Deflate | via CompressionStream, before encryption |
AES-GCM is an authenticated cipher: confidentiality and integrity. Any modification to the ciphertext makes decryption fail, so tampering is detected.
flowchart TD
PP["Passphrase"]
P2["Second passphrase<br/>(dual mode only)"]
PP --> CMB{"Dual mode?"}
P2 --> CMB
CMB -->|"yes"| COMB["Combine the two secrets<br/>(fixed separator)"]
CMB -->|"no"| KDF
COMB --> KDF["PBKDF2-SHA256<br/>32-byte salt · iterations (300k/600k/1M)"]
KDF --> KEY["256-bit AES key"]
IVN["Random 12-byte IV"] --> GCM
KEY --> GCM["AES-256-GCM"]
PAY["Payload"] --> GCM
GCM --> CT["Ciphertext + 16-byte tag"]
- Salt (32 random bytes per file) defeats precomputation and ensures the same passphrase yields different keys across files.
- Iterations default to 600,000 (selectable 300k / 600k / 1,000,000). Higher = linearly more brute-force cost.
-
IV (12 random bytes). For chunked data, each chunk's IV is unique (base IV XOR chunk index), so no
(key, IV)pair repeats.
The only readable part of a .zefer file is a small non-secret label. Everything sensitive is locked inside the ciphertext:
flowchart LR
subgraph PUB["🔓 Public header — readable by anyone"]
direction TB
H1["iterations"]
H2["compression"]
H3["mode (text/file)"]
H4["optional hint / note"]
end
subgraph SEAL["🔒 Sealed inside AES-256-GCM"]
direction TB
S1["your content"]
S2["file name / type / size"]
S3["expiration"]
S4["secret-question hash"]
S5["allowed IPs"]
S6["max attempts"]
end
Because expiration, IP rules, the secret question, and attempt limits live inside the ciphertext, nobody without the passphrase can read or edit them, and GCM authentication guarantees they were not altered.
Payloads are encrypted in 16 MB chunks, each sealed independently with a distinct IV and its own 16-byte tag. Benefits: bounded memory (huge files don't need one giant buffer), per-chunk integrity, and streaming-friendly framing (each chunk is length-prefixed — see Binary File Format).
- Dual passphrase: two secrets are combined before key derivation; both are required. Good for two-person authorization.
- Reveal key: share a file so the recipient can open it without ever seeing the main passphrase. Stored as the ZEFR3 format with two independently encrypted blocks.
Protected against
- Server compromise / data breach — there is no server holding your data.
-
Passive interception — a
.zeferfile is ciphertext; only the public header is readable. - Tampering — GCM authentication detects any change.
- Offline brute force — mitigated by 256-bit keys and high-iteration PBKDF2; ultimate strength depends on passphrase entropy (use the Password Generator and Analyzer).
- Metadata snooping — sensitive metadata is encrypted, not in the public header.
Not a substitute for
- A weak passphrase — all security ultimately rests on passphrase entropy.
- Endpoint security — a compromised device (malware, keylogger) defeats any client-side tool.
- Treating access controls as cryptography — IP allowlists and max-attempts are client-enforced policy checks; they raise the bar but the content's confidentiality always rests on AES-256-GCM.
- Post-quantum worries about a key-exchange layer — there is none; AES-256 retains a ~128-bit margin under Grover's algorithm.
See the project's Security Policy and the /security page for responsible-disclosure guidelines.
📖 Glossary — terms on this page: AES-256-GCM · PBKDF2 · salt · IV · authentication tag · key derivation · chunk · dual passphrase · reveal key · entropy · zero-knowledge. Full list in the Glossary.
📖 New to a term? See the Glossary. · Zefer · Repository · CLI · MIT © José Carrillo
Guides
- Getting Started
- How It Works
- Examples and Recipes
- Install and Self-Hosting
- Comparisons
- Troubleshooting
- FAQ
Security
Channels
Tools
Project
Reference