Security

    Android BiometricPrompt: using biometrics securely

    A 2026 view of Android BiometricPrompt binding a Keystore key via a CryptoObject so a secret is only usable after a genuine biometric match enforced by hardware, not a trusted callback

    On Android, BiometricPrompt is the standard way to authenticate a user with their fingerprint or face, and like its iOS equivalent it is easy to use in a way that only looks secure. The common mistake is treating the success callback as the security boundary: ask for biometric auth, get a success result, and proceed. That callback is a UI gate, not a guarantee, and on a compromised device it can be defeated. The secure pattern binds the biometric check to a key in the Android Keystore, so a secret is only usable after a genuine, hardware-enforced authentication. Here is how BiometricPrompt works and how to use it securely.

    Short answer

    BiometricPrompt is Android's standard biometric authentication API, and the secure way to use it is not to trust the success callback alone, which is only a UI gate, but to bind the biometric authentication to a cryptographic key in the Android Keystore. Per Android's biometric guidance, you create a Keystore key that requires user authentication and use it through a BiometricPrompt CryptoObject, so the key, and the secret it protects, can only be used after a successful biometric check enforced by hardware. Use a strong biometric class for crypto-backed authentication, and remember biometrics gate local access, not your server, which still authenticates the session.

    What you should know

    • BiometricPrompt is the standard API: for fingerprint and face authentication.
    • A success callback is not security: it is a UI gate that can be bypassed.
    • Bind to a Keystore key: use a CryptoObject tied to a key requiring authentication.
    • Hardware enforces it: the key is only usable after a genuine biometric match.
    • It does not replace server auth: it gates local access, not the backend.

    How does BiometricPrompt work?

    It presents the system biometric dialog and reports whether authentication succeeded. Your app builds a BiometricPrompt, specifies the allowed authenticators, biometrics and optionally a device-credential fallback, and shows the prompt; the system runs the fingerprint or face check and calls back with success or failure. BiometricPrompt is the modern, unified API that replaced the older fingerprint API, and it gives a consistent experience across devices. The easy path is to act on the success callback directly in your code, which works but leans entirely on trusting that result. As on iOS, how much that protects depends on what you do with the outcome: a bare success boolean is a convenience gate, not a cryptographic guarantee, so the security comes from how you tie the authentication to something real.

    What is the trap with a success boolean?

    That a result your code checks can be bypassed on a compromised device. The table contrasts the approaches.

    ApproachWhat protects the secret
    Show the prompt, trust the success callbackYour code's check; bypassable if the runtime is compromised
    Bind biometrics to a Keystore key via CryptoObjectThe hardware allows the key only after a genuine match
    No binding, secret available regardlessNothing; the gate is cosmetic

    If your app shows the prompt and then reads a secret it already holds on success, an attacker who can manipulate the runtime, on a rooted device, for instance, can make the callback report success or skip the check, since the secret was never tied to the authentication. The secure design stores the secret using a Keystore key that requires user authentication, and uses that key through a CryptoObject in the prompt, so the key is only usable after a real biometric match and the hardware enforces it. Then the authentication protects the secret, not a branch in your code that could be patched.

    How do you use it securely?

    Tie the biometric check to a Keystore key, and keep the server as the authority. Generate a key in the Android Keystore with the property that it requires user authentication, then perform the sensitive operation, decrypting a stored token or releasing a secret, through that key using a BiometricPrompt CryptoObject, so the key only works after a successful biometric authentication enforced by the hardware. Use a strong biometric class for this crypto-backed flow, since weaker biometrics may not gate a Keystore key, and decide whether to allow a device-credential fallback. Treat biometrics as gating local access to something on the device, while your backend still authenticates the session with proper tokens, because a local biometric success means nothing to your server by itself. The principle, identical to iOS, is that the secret should depend on the authentication, not a boolean.

    What to watch out for

    The first trap is trusting the BiometricPrompt success callback as if it were security, when it is a UI gate; bind sensitive data to a Keystore key instead. The second is treating a local biometric success as backend authentication, when your server still needs its own session and tokens. The third is using a weak biometric class for a crypto-backed flow, which may not properly gate the key. A pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled APK or AAB against OWASP MASVS and assesses how your app stores secrets and uses the Keystore, which complements reviewing whether your biometric gate actually protects a secret. The key binding you implement in the app.

    What to take away

    • BiometricPrompt is Android's standard biometric API, but its success callback is a UI gate, not security.
    • The secure pattern binds the biometric check to a Keystore key that requires user authentication, used via a CryptoObject, so the hardware allows the key only after a genuine match.
    • Use a strong biometric class for crypto-backed authentication, and remember biometrics gate local access, not your server, which still authenticates the session.
    • Use a pre-submission scan such as PTKD.com to check how your app stores secrets and uses the Keystore alongside its biometric flow.
    • #android
    • #biometricprompt
    • #biometrics
    • #keystore
    • #cryptoobject
    • #owasp-masvs
    • #app-security

    Frequently asked questions

    How does Android BiometricPrompt work?
    It presents the system biometric dialog and reports whether authentication succeeded. Your app builds a BiometricPrompt, specifies the allowed authenticators including an optional device-credential fallback, and shows the prompt; the system runs the fingerprint or face check and calls back with success or failure. It is the modern unified API that replaced the older fingerprint API. The easy path is to act on the success callback, but how much that protects depends on what you do with the result.
    Is a BiometricPrompt success result enough for security?
    No. A success callback is a UI gate, not a cryptographic guarantee. If your app shows the prompt and then reads a secret it already holds on success, an attacker who can manipulate the runtime on a compromised device can make the callback report success or skip the check, since the secret was never tied to the authentication. The secure design binds the authentication to a Keystore key, so the secret depends on a real biometric match, not a boolean your code trusts.
    How do I use BiometricPrompt securely?
    Generate a key in the Android Keystore that requires user authentication, then perform the sensitive operation, decrypting a stored token or releasing a secret, through that key using a BiometricPrompt CryptoObject, so the key only works after a successful biometric authentication enforced by hardware. Use a strong biometric class for this crypto-backed flow, since weaker biometrics may not gate a Keystore key, and keep your backend as the authority that authenticates the session.
    Do biometrics replace server authentication?
    No. Biometrics gate local access to something on the device, but a local biometric success means nothing to your server by itself, so your backend still needs to authenticate the session with proper tokens. Use biometrics to protect local access, such as releasing a stored token from the Keystore, and keep the server validating that token. Treating a local fingerprint or face success as backend authentication would leave your server trusting an unverified client.
    How do I check my app's biometric and key handling?
    Scan the build. A pre-submission scan such as PTKD.com reads the compiled APK or AAB against OWASP MASVS and assesses how your app stores secrets and uses the Keystore, which complements reviewing whether your biometric gate actually protects a secret or just checks a callback. If secrets are not bound to a Keystore key requiring authentication, the fix is to store them under such a key and use it through a CryptoObject so the hardware enforces the biometric check.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free