How KeyNesta encrypts your 2FA codes
Plain-language security architecture. Published 29 August 2026, updated 19 September 2026.
The one-sentence version
Your 2FA secrets are encrypted on your device with keys only you hold. KeyNesta's servers store ciphertext they cannot open, and generating codes never requires the internet at all.
This page is the plain-language version. If you would rather read the parameters — scrypt cost, per-object AAD, the sync protocol and the threat model — see the encryption architecture.
How your vault is encrypted
When you create a vault, your device generates a random 256-bit master key. That key (not your passphrase) encrypts your vault with AES-256-GCM, an authenticated cipher that detects any tampering.
Your passphrase protects the master key: it is stretched with scrypt (a deliberately memory-hard function that makes GPU brute-force attacks expensive) and the result wraps the master key. Changing your passphrase re-wraps one small block; your data is never re-encrypted or exposed in the process.
Entering a wrong passphrase simply fails authentication. There is no hint, no partial decryption, no oracle.
Zero-knowledge sync
Sync is optional. When enabled, every object (each account entry, group, space) is individually encrypted with your master key before upload. The server sees opaque ciphertext plus the minimum it needs to sync: object IDs, version numbers, timestamps. It never sees secrets, code values, account names, tags, or your spaces and groups.
Your account password authenticates you to the sync service; it can't decrypt anything. Your vault passphrase never leaves your devices. Signing in on a new device downloads ciphertext that only your passphrase can unwrap, locally.
On your devices
- iPhone & Android: the master key can be stored in the hardware-backed Keychain/Keystore behind Face ID or fingerprint. The vault locks when the app goes to the background.
- Web: the vault is stored encrypted in your browser (see the web authenticator guide); the master key exists only in memory while unlocked and is discarded on lock or after an inactivity timeout.
- Multiple vaults on one device are cryptographically independent: separate keys, separate passphrases, separate sync accounts.
What we deliberately do not do
- No invented cryptography: audited open-source implementations of standard primitives (noble-ciphers and noble-hashes for AES-256-GCM, scrypt and HMAC) only.
- No ads, no analytics SDKs harvesting behavior, no selling of any usage data. An authenticator sees your whole digital life; monetizing that is disqualifying.
- No lock-in: encrypted backups are portable files you own, and standard exports always work.
- No logging of secrets or generated codes, anywhere, ever.
Honest limits
Every security claim has limits. Here are ours:
- Your passphrase is the wall. Zero-knowledge also means we cannot reset it. A weak passphrase weakens everything, and a forgotten one without a backup means the vault stays sealed (see the one rule that matters).
- If our servers were breached, the attacker would hold your wrapped master key and could try passphrases against it offline. scrypt makes every guess expensive, but a short passphrase is still guessable. Use a long one.
- A fully compromised device (malware, malicious browser extensions) can read what you can read while a vault is unlocked. Auto-lock narrows that window; it cannot eliminate it.
- Clipboard clearing after copying a code is best-effort: operating systems keep clipboard histories we cannot fully control.
- Independent third-party cryptographic review is on our roadmap and will be published; until then, treat "secure" as "well-designed and tested," not "audited."
Questions?
Write to security@keynesta.com. Vulnerability reports are welcome and taken seriously. For the technical detail behind everything above, see the encryption and zero-knowledge architecture; if you have already lost the device, start with lost phone recovery. A field-by-field list of what the sync database holds is on what the server stores, and shipped changes are dated in the changelog.