Why I deliberately didn't bind my Keystore key to biometric auth (Flutter password manager, now open source)
▲ 2 r/Passwords+2 crossposts

Why I deliberately didn't bind my Keystore key to biometric auth (Flutter password manager, now open source)

I've been building a zero-knowledge password manager (PassKeyra) in Flutter for the past year, and I just released it under the GPL-3.0 license.

The most interesting Flutter problem was biometric unlock, and I made a deliberate trade-off I'm not 100% sure about. I'd love this community's take.

The vault is encrypted with a key derived from the master password (PBKDF2-HMAC-SHA256, AES-256-GCM), entirely in Dart. For biometric unlock, I didn't want to keep that vault key in plaintext behind a simple fingerprint, so I wrap it with a hardware AES-256-GCM key stored in the Android Keystore.

Flutter_secure_storage is great for storing secrets, but it doesn't expose the wrap/unwrap primitives I needed. So I wrote a small native Kotlin plugin (BiometricKeywrapPlugin) over a MethodChannel: wrapKeyMaterial / unwrapKeyMaterial / clearWrappingKey. StrongBox is best-effort, with a fallback, because setIsStrongBoxBacked(true) doesn't throw at build time: it throws at generateKey() via StrongBoxUnavailableException on devices that don't have it (a lot of mid-range phones and tablets).

The obvious "secure" choice is setUserAuthenticationRequired(true), so the Keystore key only decrypts after a fresh biometric auth through a CryptoObject. I deliberately chose NOT to do that.

The reason: CryptoObject-bound auth requires STRONG biometric (Class 3). That silently breaks face unlock on a huge number of devices. Many Pixels and Samsung tablets only expose Class 1/2 / WEAK / CONVENIENCE. Users would lose biometric unlock for no visible reason. So the key is non-exportable and hardware-bound, but with setUserAuthenticationRequired(false), and biometric auth is enforced at the app layer via local_auth.authenticate() BEFORE wrap/unwrap is ever called.

Once auth passes, unwrap runs without a second prompt. The honest downside, which I left as a comment in the code: the key isn't cryptographically bound to strong biometric. It's the same model as Bitwarden and 1Password, but I'd rather say it plainly than pretend it's more solid than it is. The code (it's all there, including that comment): https://github.com/Pass-Keyra/PassKeyra

 

My questions for you:

  1. Would you have forced Class 3 and accepted losing face unlock on a lot of devices?

  2. Is there a cleaner pattern to get both broad device support AND CryptoObject-level binding in Flutter?

 

Thanks for reading this far, and a special thank you to anyone who takes the time to go look at the code. That's exactly the point of open source: you shouldn't have to take my word for it.

(This is a shipped freemium app, with an ad banner in the free version. I'm posting here for the technical discussion.)

u/PassKeyra — 6 days ago

I spent ~a year solo-building a zero-knowledge, open-source password manager (Android). It's live feedback welcome.

Hey r/SideProject,

For about a year I've been building PassKeyra solo, a password manager for Android, now live on the Play Store and open source (GPL-3.0).

The idea: your vault is encrypted on-device and the master password never leaves it. Cloud sync/backup (Google Drive or OneDrive) is fully optional if you turn it on, the servers only ever get encrypted data. I wanted a genuinely usable free tier and a one-time purchase option, instead of yet another annual subscription.

The interesting/hard part:

  • Hardware-backed biometric unlock: wrapping the vault key via the Android Keystore (TEE/StrongBox) needed a small native Kotlin plugin, because the Flutter package didn't expose it.
  • Staying honest about trade-offs: the free tier has a discreet ad banner (gone in Premium) and sync uses Firebase so I open-sourced the whole thing, to let people verify the zero-knowledge claims instead of trusting my word.

Honestly my biggest challenge now is being a complete unknown in a category dominated by Bitwarden and the built-in managers. So I'm here for blunt feedback landing page, store listing, the model, anything.

What would make you trust (or not trust) a password manager from a solo dev?

u/PassKeyra — 15 days ago

I built PassKeyra - password manager

Hey r/droidappshowcase,

I've been working on PassKeyra for a couple of years and I'm ready to share it more widely.

A password manager that encrypts everything locally before anything leaves your device. Cloud sync and backup (Google Drive or OneDrive) are opt-in — if you use them, the servers only receive encrypted blobs. Not readable by Google, Microsoft, or me.

I was frustrated by the lack of transparent, affordable alternatives. Most require trusting a closed-source backend. Bitwarden is solid but the mobile UX felt less polished. 1Password is beautifully designed but ~€36/year. I wanted something with a one-time purchase option and a genuinely usable free tier.

Free features:

- Unlimited vault entries

- Biometric unlock (fingerprint / face ID)

- Password generator

- Works fully offline

- Available in FR / EN / ES

- Light, dark, or auto theme

Premium — €2.99/month or €29.99 lifetime:

- Auto-sync across all your devices

- Automatic cloud backup (Google Drive or OneDrive)

- Security audit: detects weak, old, or reused passwords

- Multiple passwords per entry

- No ads

Open source: GPL-3.0 since May 2026

Play Store: https://play.google.com/store/apps/details?id=com.passkeyra.app&utm_source=reddit_androidapps&utm_medium=social&utm_campaign=launch

Happy to answer any questions about the security model or feature decisions.

u/PassKeyra — 1 month ago