Security

What's protected, what isn't, and how.


Transport encryption

All sync traffic between phone and computer is encrypted with NaCl secretbox after an X25519 key exchange. Each connection generates fresh ephemeral keypairs — no long-lived keys. The shared secret is derived with nacl.box.before() and used for nacl.secretbox() with random 24-byte nonces. See Sync Protocol for the wire-level details.

Pairing secret

The pairing secret (a random UUID) is the only authentication factor. It's established during pairing and validated during every handshake using a timing-safe comparison. The secret is transmitted only inside the encrypted channel — never in plaintext on the wire.

Storage: The pairing secret is stored in plaintext on both devices (AsyncStorage on mobile, JSON file on the computer). It is not protected by the OS keychain. On a jailbroken phone or a shared Windows account, the secret is readable from disk.

App lock

When enabled, the phone app requires biometric authentication or device passcode/PIN/pattern when resuming from the background. This is a UI gate — it doesn't encrypt or decrypt anything.

Locked lists

The Locked Lists tab requires biometric authentication or device credentials on the phone. On the computer, locked lists are not gated — the assumption is your computer is already a secured environment. This protects against casual shoulder-surfing on the phone, not forensic extraction. The locked list data is stored in the same plaintext stores as regular lists — AsyncStorage on mobile, JSON files on the computer. See Locked Lists.

Backup encryption

Computer backups can be encrypted with a user-provided password using AES-GCM with PBKDF2 key derivation. Plaintext backups are also available. See Backup.

What is NOT encrypted at rest

Threat model

JotBunker protects against:

JotBunker does not protect against:


See also: Pairing | Sync Protocol | Backup | Data Storage