Skip to content
All guides

TECHNICAL GUIDE

Cryptography

What encrypts the vault, how passwords and recovery codes unlock its key, and what changes when you replace a secret.

What encrypts the vault

Cryptex Vault encrypts the serialized vault with a randomly generated 256-bit data-encryption key, or DEK. AES-256-GCM encrypts the data and checks its integrity during decryption.

The password protects access to this key. A key-encryption key, or KEK, wraps the DEK using AES Key Wrap. The vault envelope stores two wrapped copies in separate key slots: one for normal unlocking and one for recovery.

PRIMARY UNLOCK
Master password + password saltArgon2id uses a random 16-byte salt to derive 32 bytes of password material.
HKDF-SHA-256
Primary key-encryption keyWithout additional protectionInput: password-derived material. Salt: a separate random 16-byte HKDF salt.With additional protectionInput: factor key material. Salt: the 32-byte password-derived material above.Both use the vault ID in the HKDF context.
AES Key Wrap
Primary slotA wrapped copy of the data key
RECOVERY UNLOCK
Recovery code + recovery saltThe recovery code has its own random 16-byte salt, separate from the password salt.
Argon2id
Recovery key-encryption keyArgon2id derives the 256-bit recovery wrapping key directly from the recovery code and its separate salt.
AES Key Wrap
Recovery slotAnother wrapped copy of the same data key
Either slot unwraps the same key
Data-encryption key, or DEKRandom 256-bit key
AES-256-GCM
Encrypted vault payloadSerialized vault records
Unlocking needs one complete path, not both. Each slot stores an encrypted copy of the data key, not the password or recovery code. Random salts are stored with the envelope. With additional protection, the HKDF salt is instead secret password-derived material, recomputed during unlocking.

Unlock factors and recovery

Argon2id derives 256 bits of key material from the master password and a stored random salt. Without additional protection, HKDF-SHA-256 uses that material and a separate stored salt to derive the primary KEK.

With additional protection, HKDF instead uses the factor's key material as its input and the password-derived value as its salt. Both are needed to derive the primary KEK. In either case, HKDF includes the vault ID in its context string.

Protection phrase
A generated phrase contains 128 or 256 bits of entropy. Argon2id derives its key material with a separate salt. The client can retain that derived material locally, so the phrase need not be entered on every unlock. Restoring on a fresh device requires the phrase unless the vault recovery code is used.
WebAuthn PRF
A compatible authenticator supplies a reproducible 32-byte output through the WebAuthn PRF extension. This output supplies the additional key material directly, without a second Argon2id step. The password is still required for primary unlocking, along with access to the enrolled credential through a compatible browser and authenticator.
Vault recovery code
Creation generates a 24-word BIP39 mnemonic from 256 bits of entropy. Argon2id derives a separate recovery KEK that unwraps the same DEK. This path does not require the master password or additional factor.

Changing keys and secrets

Rewrapping changes how an existing data key is unlocked. Data-key rotation replaces that key and encrypts the vault again. These operations first require access to the existing DEK through the primary or recovery slot.

OperationKey slotsVault data key and payload
Change master passwordRebuilds the primary slot. Recovery slot is unchanged.Same DEK and ciphertext.
Add, change, or remove additional protectionRebuilds the primary slot using the new factor settings. Recovery slot is unchanged.Same DEK and ciphertext.
Replace recovery codeRebuilds the recovery slot. Primary slot is unchanged.Same DEK and ciphertext.
Rotate data-encryption keyRebuilds both slots and generates a new recovery code.New DEK, fresh IV, and re-encrypted payload.

The first three rows describe changes without optional data-key rotation. All changes apply to this local vault. Linked devices keep their own keys, and existing backups keep their original envelopes and unlock secrets. Adding protection or rotating a key does not retroactively secure an older backup.

Format and parameters

These values describe the current version 3 vault envelope. Argon2id defaults apply when creating new key slots; unlocking an existing vault uses the parameters recorded in its slot.

Vault payload
AES-256-GCM with a random 256-bit DEK. Each payload encryption generates a fresh random 12-byte IV using crypto.getRandomValues. Web Crypto uses its default 128-bit authentication tag.
Password derivation
Argon2id v1.3 through libsodium, producing 32 bytes. Defaults are 256 MiB of memory and 3 passes. Password and recovery derivation use separate random 16-byte salts.
Primary KEK
HKDF-SHA-256 produces a 256-bit AES-KW key. Its context is cryptex/kek/v1| followed by the vault ID. Without additional protection, the HKDF salt is a separate random 16-byte value.
Recovery KEK
The 32-byte Argon2id output from the recovery code is imported directly as a 256-bit AES-KW key.
Wrapped keys
Each slot contains a 40-byte AES-KW wrapped DEK, plus the derivation parameters needed to open it. Random salts and IVs are stored alongside the encrypted vault. They do not need to be kept confidential and cannot decrypt the vault on their own.

Vault payload encryption does not supply additional authenticated data to AES-GCM. The vault-ID context above belongs to primary-key derivation; it should not be confused with the transcript-bound associated data used in synchronization.

Older blob readers support migration from the earlier AES/PBKDF2 and XChaCha20-Poly1305 formats. Those formats are separate from the current envelope described here.

Session cryptography

Linked devices use separate synchronization keys to establish an encrypted session. These keys are distinct from the DEK that encrypts each local vault.

PrimitivePurpose
ML-KEM-768Establishes shared secret material for the session.
ML-DSA-65Authenticates the handshake using signing keys exchanged during linking.
HKDF-SHA-256Derives the AES session key from the shared secret and handshake context.
AES-256-GCMEncrypts messages with fresh random nonces. Associated data binds messages to the handshake and sequence; the receiver checks sequence numbers.

Initial linking uses a mnemonic-protected invitation. The sender signs the transfer's key-encapsulation context with ML-DSA, and the receiver verifies it using the sender key in the invitation. See session establishment for the protocol sequence and message checks.

Backups and exports

A manual .cryx backup contains the encrypted vault envelope. Managed backups use the same restore format and are encrypted locally before upload. They retain the key slots needed for decryption.

The backup service receives ciphertext, its byte size, and a SHA-256 checksum. The checksum checks transfer integrity; AES-GCM authenticates the encrypted payload when the client decrypts it.

A JSON migration export is not encrypted. It contains readable credential data and has no protection from the vault password or recovery code. See Backups for backup and restore instructions.

Implementation references

For security assumptions and limits, see the Threat model. Audit status is listed on the Security page.