1

My app requires a password to use. The user enters their password first time they open the app, I send the password to the server side and they do the usual hashing+salting routine. Next time the user enters the password, I send it to the back-end to verify and send me a temporary token to be used for further queries. It works fine.

Now I want the user to be able to sign in with biometrics (fingerprint, etc). Android handles that and lets me know if the user passed the biometric authentication. But then I don't have the password to send to the back-end and get the token. How do I handle that? I suppose I could store the password and send that if biometric auth passes, but that sounds like a massive security vulnerability. I could encrypt the password, but that creates the issue of storing the encryption key.

My question is, what is the usual way to handle biometric sign in like this? Is there a secure way to store passwords so it's only visible to my application? SharedPreferences can be bypassed with root access, so that's probably not an option. Detecting rooted phones is also not reliable with "systemless root" and such.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • "Is there a secure way to store passwords so it's only visible to my application?" -- store it in the `AndroidKeyStore`, where you need the biometrics to get the decrypted value. Or, instead of saving the password that way, save some long-lived API token that you use instead of the password, where the long-lived API token is used to get your session token. – CommonsWare Jul 24 '21 at 13:26
  • 1
    Why don't you work with **Encrypted Shared Preferences** (https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences). There is another article (https://developer.android.com/topic/security/data) that says "*Note: The Security library doesn't support BiometricPrompt at the cryptographic-operation level.*" but that means that you need to authenticate only with BiometricPrompt and "onSuccess" you get the encrypted data back and send it to the server. – Michael Fehr Jul 24 '21 at 14:12
  • I checked with a simple Android app, and you can store your passwords with Encrypted Shared Preferences and later load (and send to the server of course) the encrypted data after a successful biometric authentication is run. – Michael Fehr Jul 24 '21 at 21:28
  • @CommonsWare Android KeyStore seems to wipe data sometimes. [Here](https://doridori.github.io/android-security-the-forgetful-keystore/) is a post I found. It would be a problem if I lost the password randomly. Is there a way around? – Aykhan Hagverdili Jul 26 '21 at 05:45
  • @MichaelFehr [This](https://stackoverflow.com/questions/60388448/proper-usage-of-encryptedsharedpreferences) stack overflow post claims that EncryptedSharedPreferences can be bypassed with api hooking. – Aykhan Hagverdili Jul 26 '21 at 05:46
  • "It would be a problem if I lost the password randomly" -- according to that article, the password is not lost randomly. The keys are lost if the user makes a significant change to their device security. You are going to need some form of account recovery option, regardless of the biometrics, because phones break, get lost, etc. That account recovery option would also be used in the scenario where your key got invalidated through device security changes. – CommonsWare Jul 26 '21 at 11:10
  • "This stack overflow post claims that EncryptedSharedPreferences can be bypassed with api hooking." -- that requires a rooted device. Every form of security is at risk of being broken on a rooted device, other than having the user type in a passphrase from memory. – CommonsWare Jul 26 '21 at 11:12

1 Answers1

0

I combined the suggestions in comments and stored sensitive information in EncryptedSharedPreferences and stored the key for that in AndroidKeyStore. It works fine, the only probelm is that the MasterKey required for EncryptedSharedPreferences doesn't work on API 22 and 21. Here is a workaround, but I don't know how secure it is.

Seems like it can still be bypassed if the phone is rooted, but now it's more difficult.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93