Encryption & Decryption
Argon uses a layered encryption scheme where the server never possesses the keys needed to decrypt vault data. Every secret is encrypted client-side before transmission and decrypted client-side after retrieval. The server is a dumb encrypted blob store.Key Derivation
When a user registers, the desktop app derives cryptographic keys from their master password using Argon2id — a memory-hard key derivation function resistant to GPU and ASIC brute-force attacks.| Derived Key | Purpose | Leaves Client? |
|---|---|---|
auth_verifier | Stored on server, used to verify login challenges | Yes (hash only) |
encryption_key | Encrypts/decrypts the user’s private keys | Never |
auth_verifier is a SHA-256 hash of the auth key — the server stores this hash and uses it to verify HMAC challenge-response proofs during login. Even if the server database is stolen, the attacker gets a hash of a hash of an Argon2id derivation — computationally infeasible to reverse.
Key Pairs
Each user has two asymmetric key pairs, generated client-side at registration:| Key Pair | Algorithm | Purpose |
|---|---|---|
| X25519 | Curve25519 Diffie-Hellman | Key exchange — used to create shared secrets for envelope encryption |
| Ed25519 | Edwards-curve Digital Signature | Signing — used to verify entry integrity and authorship |
encryption_key (derived from the master password) using XChaCha20-Poly1305 before being uploaded to the server. The server stores:
PublicKeyX25519— plaintext (public keys are meant to be shared)PublicKeyEd25519— plaintextEncryptedPrivateKeyX25519— ciphertext (encrypted with user’s encryption_key)EncryptedPrivateKeyEd25519— ciphertext (encrypted with user’s encryption_key)
Envelope Encryption
Every vault entry (login, note, card, identity, file) is encrypted with its own random Data Encryption Key (DEK). The DEK is then wrapped (encrypted) to each user who should have access, creating an envelope per user.Why Envelope Encryption?
- Per-entry keys — Compromising one DEK exposes one entry, not the entire vault.
- Efficient sharing — To grant access, wrap the existing DEK to the new user’s public key. No re-encryption of the (potentially large) payload.
- Revocation — To revoke access, delete the user’s envelope. They can no longer unwrap the DEK.
- Key rotation — Rotate a DEK by re-encrypting the payload and issuing new envelopes, without changing any user’s key pair.
Cipher Suite
| Operation | Algorithm | Key Size | Nonce Size |
|---|---|---|---|
| Password hashing | Argon2id | 256-bit output | 128-bit salt |
| Symmetric encryption | XChaCha20-Poly1305 | 256-bit | 192-bit |
| Key exchange | X25519 (Curve25519) | 256-bit | N/A |
| Key derivation | HKDF-SHA256 | 256-bit output | Context-dependent |
| Signatures | Ed25519 | 256-bit | N/A |
| Auth verification | HMAC-SHA256 | 256-bit | 256-bit nonce |
| External file shares | AES-256-GCM | 256-bit | 96-bit |
| Server-side secrets | XChaCha20-Poly1305 | 256-bit (HKDF from CA key) | 192-bit |
- 192-bit nonce eliminates nonce collision risk even with random generation
- No padding oracle attacks (stream cipher + AEAD)
- Constant-time implementation in Go’s
golang.org/x/crypto - Faster than AES-GCM on platforms without AES-NI hardware acceleration
Server-Side Encryption
Certain server-managed secrets (SMTP credentials, escrow keys) are encrypted at rest on the server. These use XChaCha20-Poly1305 with a key derived from the CA private key:- The encryption key is deterministically derived from the CA key — no separate key storage.
- If the CA key is compromised, server-side secrets are exposed (but vault data is not — vault encryption keys are derived from user passwords, not the CA key).
- If the database file is stolen without the CA key, server-side secrets remain encrypted.
What the Server Sees
| Data | Server Visibility |
|---|---|
| Vault entry payloads | Encrypted blob — cannot decrypt |
| Entry DEKs | Wrapped in user envelopes — cannot decrypt |
| User private keys | Encrypted with password-derived key — cannot decrypt |
| User public keys | Plaintext (by design — public keys are not secret) |
| Auth verifiers | SHA-256 hash of Argon2id output — cannot reverse |
| SMTP passwords | Encrypted with CA-derived key — can decrypt (server needs to send email) |
| Filenames, tags, metadata | Plaintext (for search/filter — future: encrypted metadata) |
| Audit logs | Plaintext (operational necessity) |

