RabbitKey derives a key from your master password and uses it to seal every vault entry before anything is written to disk. This article follows that path end to end: from the password you type to the ciphertext stored on your device.
A master password is a human-memorable string. Encryption requires a fixed-length, high-entropy key. The gap between these two things is bridged by a Key Derivation Function (KDF).
RabbitKey uses PBKDF2-HMAC-SHA256 with the following parameters:
The salt is not secret. Its purpose is uniqueness: two users with the same password produce completely different keys because their salts differ.
OWASP's password-storage guidance has historically put 100,000 in range for PBKDF2-HMAC-SHA256, while NIST's more recent guidance recommends 600,000. RabbitKey's current count is 100,000 — below that newer recommendation. It raises the cost of an offline attack against a strong master password, but it is not a substitute for choosing a strong password in the first place. The account record stores the KDF identifier and its parameters, so the iteration count can be raised in a future version and existing vaults re-wrapped on unlock. (PBKDF2 is the only KDF implemented today; do not assume a memory-hard function such as Argon2 is in use.)
The key derived from your password does not directly encrypt your entries. RabbitKey uses an envelope (key-wrapping) design:
This indirection has a concrete payoff: changing your master password does not re-encrypt your whole vault. Only the small wrapped-master-key blob is re-wrapped with the new password-derived key. It is also why your Recovery Kit — which is the master key itself, encoded — keeps working after a password change: the underlying master key never changed.
Both the wrapping step and the entries themselves use XChaCha20-Poly1305, an Authenticated Encryption with Associated Data (AEAD) construction.
The key parameters:
| Parameter | Value |
|---|---|
| Key size | 256 bits |
| Nonce size | 192 bits (24 bytes) |
| Authentication tag | Poly1305 MAC (128 bits) |
A fresh, random 24-byte nonce is generated for every encryption operation. The nonce is stored alongside the ciphertext — it is not secret, but it must never repeat for the same key. XChaCha20's extended 192-bit nonce makes collisions negligibly probable even across billions of operations.
AEAD provides two guarantees simultaneously:
This means RabbitKey doesn't just hide your passwords — it detects tampering. A corrupted or modified vault file will be rejected rather than silently decrypted into wrong data.
The master password and the derived key are held only in memory during a session — neither is written to disk. What persists on disk is the salt, the wrapped master key, and the ciphertext.
Both are secure AEAD ciphers. XChaCha20-Poly1305 has two practical advantages on mobile:
If an attacker obtains your encrypted vault — through device theft, cloud storage compromise, or any other means — they get the salt, the wrapped master key, and the ciphertext. To read anything, they must recover the master key, which means decrypting the wrapped master key, which means deriving the password-derived key through PBKDF2. That puts them back at guessing your master password, paying the 100,000-iteration cost on every attempt. There is no shortcut that skips the password.
All of this happens on your device, before any sync. Your cloud provider receives ciphertext only — see How Zero-Knowledge Sync Works. For why this is an architectural property rather than a promise, see Local-First Security Architecture & Threat Model. And for what happens if you lose your master password, see Your Recovery Kit, Explained.