# Peach for Android A free, open source, local-first password manager. Your vault stays on the device, encrypted with AES-256-GCM and protected by Argon2id. Sync between your devices happens over an end-to-end authenticated Noise channel; the cloud relay only forwards ciphertext it cannot read. There are no accounts, no servers holding your data, and no subscription required. Peach pairs with the Peach browser extension, prints encrypted backups as Aztec codes on paper, autofills inline in apps and browsers, and stores passkeys alongside passwords. **Current version:** v2.9.20 **License:** GPL v3 **Source:** [kepr.uk/peach-android](https://kepr.uk/peach-android) --- ## Security ### Cryptographic primitives - **Key derivation** — Argon2id (`m=64 MiB`, `t=3`, `p=4`, 32-byte output, 16-byte CSPRNG salt) - **Vault encryption** — AES-256-GCM with a fresh 96-bit random nonce per encrypt and 128-bit authentication tag - **Sync handshake** — Noise NK (pairing) and Noise KK (adoption), `25519_ChaChaPoly_BLAKE2s` cipher suite - **Per-entry sync envelope** — distinct HKDF-derived AES-256-GCM key per entry, AAD bound to the entry id so a ciphertext cannot be replayed between slots - **Keyed storage** — paired-device and license stores use `EncryptedSharedPreferences`; vault slots are AES-GCM-sealed blobs in plain prefs (only the salt is cleartext, matching the browser model) - **Biometric escrow** — hardware-backed AndroidKeyStore AES-256-GCM key with `setUserAuthenticationRequired(true)` and `setInvalidatedByBiometricEnrollment(true)` - **Codex (paper backup)** — GF(2⁸) Reed-Solomon with zstd compression and Aztec codes at 25% ECC - **Checksums** — BLAKE3 throughout ### Key handling - Master key and derived key are zeroed on lock and in `finally` blocks along all transient paths - No secret material is ever logged. There is no online breach check — no password hash or plaintext is ever transmitted anywhere - `allowBackup="false"` + `fullBackupContent="false"` — vault does not participate in Android Auto Backup ### Tested against published vectors All primitive implementations are pinned to published test vectors in `docs/CRYPTOGRAPHIC-TEST-VECTORS.md`: - RFC 9106 §5.3 Argon2id - NIST CAVP `gcmDecrypt256.rsp` (group `PTlen=128`, `AADlen=0`, `Taglen=128`) - BLAKE3 official `input_len=1024` reference input - Cacophony Noise NK / KK transcript catalog (shared with `peach-browser/crypto-core`) The canonical Noise core (X25519, ChaCha20-Poly1305, BLAKE2s, nonce state, rekey) lives in the Rust crate at `../peach-browser/crypto-core` and is driven from this app via JNI — see `docs/NOISE-CORE-PROVENANCE.md`. Every cryptographic decision in this codebase is byte-equivalent to the browser implementation; the parity contract is documented in `docs/browser-parity-map.md`.