2

I'm looking for the best practices regarding alternative authentication from our mobile app using fingerprint/touchID/FaceId.

We have the following architecture :

  • Database : PostgreSQL
  • Backend : REST API in .net core 2.2
  • Clients :
    • Angular2 web client
    • A mobile app in Xamarin Forms <--- This is where magic should happens

For the moment, our clients authenticate to the REST API using username/password and receive a JWT token. The token is then attached to each secured request to the API.

What I'm trying to achieve

It is not always convenient for users to type the password from the mobile keyboard, so I'm trying to implement an easier way to login using biometric authentication such as fingerprint, faceID, touchID...

In my opinion, the workflow would be the following :

  • User login from the mobile app the first time using username / password combination
  • If the device allow it, ask the user to use biometric
  • Generate a token an send it to the API
  • store the token in Secure Storage (Keystore / Keychain)
  • Use this token to login instead of password

We always have the classic username/password fallback.

I read a lot of post here on stackoverflow, and searched on Google for a solution but none seems to explain a use case with the backend security implementation.

I have implemented the fingerprint scanner on my app mobile and get the success callback. I'm using this library in my Xamarin project to get the biometric authentication : https://github.com/smstuebe/xamarin-fingerprint

Could you please advise me on how to implement it ? Is storing a common token between backend and client the best way ? Is the keystore/Keychain secure ? Am I missing something ?

Many thanks,

Regards

Alex
  • 21
  • 1
  • 2

2 Answers2

5

Keychain is the most secure place on your device. You can add jailbreak detection measures to improve security and delete the token from keychain and clear it from memory when you detect jailbreak (obfuscate this code). As for the token, I would generate it on the backend side and pass it back to the client as the auth call response. Then store it in the keychain if the user chooses with bimetric prompt for access. Then for every call, you would add this token to the request header. That's how the backend identifies you.

Levi
  • 7,313
  • 2
  • 32
  • 44
3

As I understand your problem you can design your solution according to below steps.

  1. Generate AsymmetricKeyPair at client end.
  2. Share the public key with your backend server.
  3. Encrypt the authenticationToken with public key at backend server.
  4. Share the encryptedToken to client app and save it locally at device.
  5. Use biometric apis to get the access of private key. (Only authenticated user will be able to get the access.
  6. Decrypt the encryptedToken and use it for further authentication.

You can refer the design in this android blog: It has provided design for Android App you can take it as reference and create the similar for Xamarin. https://android-developers.googleblog.com/2015/10/new-in-android-samples-authenticating.html

Fingerprint API are deprecated you will need to use BiometricPrompt BiometricPrompt with cryptoobject

Better to store encrypted data locally at device. Device keystore and keyoperations are secure if runs under TEE(Trusted Execution Environment) environment. You can check if TEE supported for android using below API:

isInsideSecureHardware

Android Keystore System https://developer.android.com/training/articles/keystore https://developer.android.com/reference/android/security/keystore/KeyInfo.html#isInsideSecureHardware()

takharsh
  • 2,258
  • 1
  • 21
  • 26
  • 1
    Hi Takharsh, thank you for taking the time. What's the benefits of encrypting the authenticationToken with public key at backend side ? When using it for authentication it will not be encrypted, right ? The encryption of request payload is managed by HTTPS in my opinion. – Alex Jan 03 '20 at 08:40
  • @Alex Encryption is only needed if you want to store it locally at device(sqlite/preferences) so that it cannot be misused if extracted out. I believe you will need to store as user will be using biometric to authenticate and then decrypt the token and send to backend lazily without blocking the UI. You can create solution according to your requirement/business. I have provided just reference design according to your query. – takharsh Jan 03 '20 at 12:35
  • 1
    Hi @takharsh, i have a question, where is the private key saved on the device? because if i save the key on Secure Storage (Keystore / Keychain) is no the same security that just save the token on the same place, this way i can avoid extra steps like Encrypt the token. – Rodrigo porras Jul 19 '21 at 18:22
  • @Rodrigoporras: Cryptographic keys can be stored in Keystore. In latest android devices there is a separate storage and cpu for cryptographic operations(Trusted Execution Environmen/Inside secure hardware)[https://developer.android.com/training/articles/security-key-attestation]. Only keys can be generated and stored in Android Keystore not any other data/tokens. Please refer: https://developer.android.com/training/articles/keystore – takharsh Jul 20 '21 at 03:15