In short: Your financial records are end-to-end encrypted on the phone before sync; your password and recovery key never leave it; and we only claim what we can show.
On your device
- The Room database is encrypted with SQLCipher. Its passphrase is random and kept in EncryptedSharedPreferences backed by the Android Keystore.
- Tokens and keys are stored in encrypted preferences.
- Optional biometric sign-in uses a Keystore key that requires strong biometrics.
Before upload: end-to-end encryption
Every synced record is encrypted with a random 256-bit data key using AES-256-GCM. On the server the data key exists only in wrapped form: once under a key derived from your password and once under a key derived from your recovery key.
Protocol v2: the device derives a master key with PBKDF2-HMAC-SHA256 (NFKC-normalised password, 600,000 iterations, per-account salt) and splits it with HKDF into two independent values — a wrapping key that never leaves the device and an authentication secret that is the only thing sent to the server. Recovery works the same way with a random 256-bit recovery key (a derived proof is sent, never the key). Envelopes are AES-256-GCM, bound to their purpose through AAD. The server therefore holds neither the password, nor the recovery key, nor any key able to unwrap the data key.
Authentication
- The password-derived authentication secret is hashed again with Argon2id, so a database leak yields nothing directly usable.
- Clients refuse KDF parameters below the supported minimum.
- Short-lived JWT access tokens (HS256, issuer-checked, session-versioned) and rotating refresh tokens with reuse detection.
- Account lockout after repeated failures, OTP attempt limits, and per-IP and per-user rate limiting.
- New-device alerts and remote sign-out.
Transport & deployment
- HTTPS only (cleartext is permitted solely in debug builds).
- The database and API are reachable only on the internal Docker network, and production start-up refuses weak or missing secrets.
Screen privacy & backups
The app window is FLAG_SECURE by default (no screenshots, blank Recents), user-switchable in Settings. Android backup and device transfer are fully excluded.
Scope & limits (please read)
- Financial records are end-to-end encrypted: neither the operator nor an attacker who controls the server can decrypt them without guessing the user’s password. The residual risk is offline guessing of weak passwords by someone who captures the authentication secret (the same model as mainstream password managers), which is why long unique passwords are encouraged and the KDF is expensive.
- Not covered by the encryption: account metadata the service needs to operate (phone number, profile fields, device list, timing and size of sync traffic). That is why we do not call Cidna “zero-knowledge”.
- If you lose both the password and the recovery key, synced data cannot be recovered.
- Security libraries are not a substitute for an independent audit.
Reporting a vulnerability
Please report security issues privately by email to cidna.app@gmail.com and do not open a public issue. security.txt