tink icon indicating copy to clipboard operation
tink copied to clipboard

Android BiometricPrompt and setUserAuthenticationRequired

Open stravag opened this issue 5 years ago • 8 comments

Hi I just tried the tink android flavor in combination with the new biometric prompt. I got it to work but unfortunately the key that tink creates does not contain the setUserAuthenticationRequired flag, which would be nice when working with fingerprint auth.

Do you see a way this could be added? I guess for a proper integration, both the AndroidX Biometric team and tink team would have to make some changes.

https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt.html#authenticate(android.hardware.biometrics.BiometricPrompt.CryptoObject,%2520android.os.CancellationSignal,%2520java.util.concurrent.Executor,%2520android.hardware.biometrics.BiometricPrompt.AuthenticationCallback)

stravag avatar May 19 '19 19:05 stravag

When I wrote AndroidKeysetManager I thought about adding support for user authentication, but decided not to because I didn't want to/know best way to add to Tink an Android UI component that prompt users for authentication. Now with BiometricPrompt, it looks like there would be a native system prompt. This is nice, but there's still a potential issue.

It looks like when Android Keystore unlocks a key, it only unlocks a Cipher object encapsulating that key, not the key alias. This means other Cipher instances obtained from the same key alias need to be independently unlocked before they can be used. The problem is when you use Tink with a master key, you give Tink a key alias. This means Tink has to unlock the key alias, but I'm not sure the best place to do it. Maybe simply passing the unlocked Cipher object to Tink would be easier. I'll take a look and update this bug once I've got a working demo.

Edit: slightly rephrasing words.

thaidn avatar May 28 '19 20:05 thaidn

I failed to use setUserAuthenticationRequired() in combination with the androidx.biometric:biometric:1.0.0-alpha04 library.

I tried the following code, using the sparsely documented CryptoObject API. Note that secretKey was generated beforehand with setUserAuthenticationRequired(true).

secretKey = (SecretKey)androidKeyStore.getKey("my_key_alias", null);
cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec); // Fails with UserNotAuthenticatedException!!!
cryptoObject = new BiometricPrompt.CryptoObject(cipher);
biometricPrompt.authenticate(promptInfo, cryptoObject);

The above code does not even manage to initialize the cipher object because it throws a premature UserNotAuthenticatedException.

To be honest, I do not even fully understand how we are supposed to tell the BiometricPrompt API to unlock a particular SecretKey with a particular key alias.

fkirc avatar Jul 14 '19 17:07 fkirc

Never mind, I solved the problem with the help of this sample code: https://github.com/stravag/android-sample-biometric-prompt

The problem was an erroneous call to setUserAuthenticationValidityDurationSeconds(int). The rest of my code was correct.

fkirc avatar Jul 14 '19 22:07 fkirc

Thanks for the update, closing.

thaidn avatar Jul 23 '19 20:07 thaidn

Never mind, I solved the problem with the help of this sample code: https://github.com/stravag/android-sample-biometric-prompt

The sample code does not use setUserAuthenticationRequired in the tink example, so the fingerprint is not needed to actually decrypt the text and can be removed while the decryption still works. Can you post an example how you used tink with a key created with setUserAuthenticationRequired?

nioncode avatar Jul 27 '19 13:07 nioncode

@thaidn the code in the solution doesn't require androidx.BiometricPrompt to be used with Tink. It just connect Tink as next actio nafter successful authentication. But it doesn't force fingerprint to be authenticated. Do you have some solution how to use Tink with biometricPrompt to use setUserAuthenticationReqired or somehow connect Tink with resulted cryptoObject?

@fkirc could you explain more how did you conenct Tink withh setUserAuthenticationReqired?

kotoMJ avatar Aug 21 '19 06:08 kotoMJ

I do not have a solution with Tink, but I rolled my own solution instead: https://github.com/fkirc/secure-zip-notes/tree/master/app/src/main/java/com/ditronic/securezipnotes

Note that I also implemented a fallback mode for the case that the setUserAuthenticationRequired code throws an exception (which can happen at any time).

fkirc avatar Aug 21 '19 13:08 fkirc

Never mind, I solved the problem with the help of this sample code: https://github.com/stravag/android-sample-biometric-prompt

The sample code does not use setUserAuthenticationRequired in the tink example

As author of the example code and this issue I can confirm that the mentioned sample does NOT use setUserAuthenticationRequired which is the whole point of this issue: @thaidn please reopen.

@fkirc since this is a tink repo and the question is specifically how to make it work with tink I'm afraid I don't think your solution is of much help here.

stravag avatar Aug 22 '19 06:08 stravag

Any update on this? its more then 3 years ago and i still cant find any solution using the biometricPrompt with tink properly.

philip-haspa avatar Apr 25 '23 12:04 philip-haspa

This feature request does not align anymore with what we aim for Tink to be. We currently do not have a lot of resources to maintain AndroidKeysetManager, and hence adding to it is currently impossible for the team. I will close this.

tholenst avatar May 03 '23 15:05 tholenst