tink
tink copied to clipboard
Android BiometricPrompt and setUserAuthenticationRequired
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)
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.
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.
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.
Thanks for the update, closing.
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
?
@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?
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).
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.
Any update on this? its more then 3 years ago and i still cant find any solution using the biometricPrompt with tink properly.
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.