oblador / react-native-keychain

:key: Keychain Access for React Native
MIT License
3.12k stars 515 forks source link

[Fix] [Android] Android devices pass through biometric authentication even with passcode on unlock (Issue #518) #592

Closed nicolas-meilan closed 4 months ago

nicolas-meilan commented 1 year ago
hraschan commented 1 year ago

Would also fix #593

alexborton commented 1 year ago

Any movement on this issue as we are experiencing it too. Would be nice to have the fix implemented out the box

araratispiroglu commented 1 year ago

I've had a similar issue with this library. For me, this was happening when the app was in the foreground and the phone was locked, unlocking the phone was allowing access to the keychain item without secondary biometric verification from the app context. Currently, I'm automatically patching the file after the node modules installation. Adding .setUserAuthenticationParameters(5, (int) KeyProperties.AUTH_BIOMETRIC_STRONG) helps me to solve the bug.

lewie9021 commented 1 year ago

It worth noting .setUserAuthenticationParameters was added in API 30 (Android 11). This will mean increasing the minimum supported version of this library. A more progressive approach might be to assert the version as we build the spec to avoid an exception whenever we attempt to retrieve the value on older devices:

final int validityDuration = 5;
final KeyGenParameterSpec.Builder keyGenParameterSpecBuilder = new KeyGenParameterSpec.Builder(alias, purposes)
  .setBlockModes(BLOCK_MODE_ECB)
  .setEncryptionPaddings(PADDING_PKCS1)
  .setRandomizedEncryptionRequired(true)
  .setUserAuthenticationRequired(true)
  .setKeySize(keySize);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  keyGenParameterSpecBuilder.setUserAuthenticationParameters(validityDuration, KeyProperties.AUTH_BIOMETRIC_STRONG);
} else {
  keyGenParameterSpecBuilder.setUserAuthenticationValidityDurationSeconds(validityDuration);
}

return keyGenParameterSpecBuilder;
alemarra89 commented 11 months ago

Hi all, can I ask you why default validityDuration is 5? I notice that KeyProperties.AUTH_BIOMETRIC_STRONG value is 2, as documented here: https://developer.android.com/reference/android/security/keystore/KeyProperties#AUTH_BIOMETRIC_STRONG

lewie9021 commented 11 months ago

I believe historically this has been lower than 5 seconds but there's been issues with older devices where they simply aren't fast enough to decrypt the data so methods like getGenericPassword fail every time

Edit: here's the PR and comment that initiated it for reference:

lewie9021 commented 11 months ago

The value you're referring to is simply the enum's underlying constant value. It's not that it sets it to 2 seconds from what I understand. That is handled when building the KeyGenParameterSpec via methods such as setUserAuthenticationParameters and setUserAuthenticationValidityDurationSeconds

alemarra89 commented 11 months ago

Thanks for the clarifications @lewie9021 I agree with you, also because I found the documentation of what you claim: https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec.Builder#setUserAuthenticationParameters(int,%20int)

AntoineThibi commented 10 months ago

I have used your solution @lewie9021 to keep compatibility with Android SDK < 30. It works great ! For SDK < 30, I just disable the option to access biometry for 5 seconds after coming back to the app. It's not great but I guess there are no real way to insure that the biometry is used to unlock the keystore on those version...

P0labrD commented 9 months ago

🆙 @oblador is there a reason not to approve and merge these changes? 🙂

androideveloper commented 4 months ago

Hi! I've merged the newer PR, closing this one 🙏