Şifre Kasam
A multi-user local password manager in Flutter. Records are encrypted on-device with AES-256-GCM, under a key derived from the master password with Argon2id.
Most password managers are cloud-based. I wanted a vault that stays on one device, needs no internet connection and supports several people sharing the same phone.
- The vault key is derived from the master password with Argon2id (19 MiB, 2 passes). Every user gets their own random salt, so two people with the same password never share a key.
- Records are encrypted with AES-256-GCM. A fresh nonce per write means even the fact that two accounts share a password does not leak.
- The password is never stored, and neither is a hash of it: login works by checking whether a fixed marker encrypted under the key can be decrypted.
- For records coming from the old plain-text version I wrote a migration that runs in a single transaction — nothing is lost.
A solo project, entirely mine.
The vault is encrypted now, and the crypto layer is covered by tests: round-trip, nonce randomness, wrong-password rejection, tamper detection and a measurement of key-derivation cost. The app is still fully offline.
Encryption is in, but that is not the whole security surface. The vault key lives only in process memory, not in the OS keystore. A copied password stays on the clipboard indefinitely, screenshots are not blocked, and the vault does not auto-lock when the app goes to the background. All of it is listed in the README.
The real lesson came from an unexpected place. The app used a 4-digit PIN, and deriving the key from it would have made the encryption theatre. I measured it on my own machine: one Argon2id derivation takes ~220 ms, so all 10,000 possibilities fall in 37 minutes. A key’s strength comes from the password’s entropy, not from the KDF — the KDF only supplies the multiplier. I dropped the PIN for a master password and left a test that fails if that measured cost ever regresses.
Flutter · Dart · SQLite · sqflite · Argon2id · AES-256-GCM