oblador / react-native-keychain

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

Android: Biometric Prompt not showing again #504

Open AhmedFarazQaimkhani opened 2 years ago

AhmedFarazQaimkhani commented 2 years ago

Biometric Prompt not showing again when click on login via biometric after unlocking device while on Login Screen. It logs in without showing prompt.

Screenshot 2021-09-13 at 6 34 01 PM
anhquan291 commented 2 years ago

await Keychain.setGenericPassword(username, password, { accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY, accessible: Keychain.ACCESSIBLE.ALWAYS, authenticationType: Keychain.AUTHENTICATION_TYPE.BIOMETRICS, storage: Keychain.STORAGE_TYPE.RSA, });

Facing the same issue here. Any solution, please? Thanks a lot

AlvaroBrasilia commented 2 years ago

Try to insert accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY argument in options for Keychain.getGenericPassword(options);

async load() {
    try {
      const options = {
        authenticationPrompt: {
          title: 'Authentication needed',
          subtitle: 'Subtitle',
          description: 'Some descriptive text',
          cancel: 'Cancel',
        },
        accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY,
        service: 'MAP',
      };
      const credentials = await Keychain.getGenericPassword(options);
      console.log('credentials', credentials);
      if (credentials) {
        this.setState({ ...credentials, status: 'Credentials loaded!' });
      } else {
        this.setState({ status: 'No credentials stored.' });
      }
    } catch (err) {
      this.setState({ status: 'Could not load credentials. ' + err });
    }
  }
anhquan291 commented 2 years ago

Try to insert accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY argument in options for Keychain.getGenericPassword(options);

async load() { try { const options = { authenticationPrompt: { title: 'Authentication needed', subtitle: 'Subtitle', description: 'Some descriptive text', cancel: 'Cancel', }, accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY, service: 'MAP', }; const credentials = await Keychain.getGenericPassword(options); console.log('credentials', credentials); if (credentials) { this.setState({ ...credentials, status: 'Credentials loaded!' }); } else { this.setState({ status: 'No credentials stored.' }); } } catch (err) { this.setState({ status: 'Could not load credentials. ' + err }); } }

Hi @AlvaroBrasilia , thanks for your answer.

Unfortunately, it doesn't work. The Fingerprint prompt showed only once the first time. After that still can access the data without asking for Fingerprint. Any helps, please? Thank you so much

AlvaroBrasilia commented 2 years ago

@anhquan291 did you set sevice in Keychain.setGenericPassword() and Keychain.getGenericPassword()?

AhmedFarazQaimkhani commented 2 years ago

@anhquan291 did you set sevice in Keychain.setGenericPassword() and Keychain.getGenericPassword()?

Hi @AlvaroBrasilia, thanks for your response. I'm doing the same, but still facing this issue.. I did set service in Keychain.setGenericPassword() and Keychain.getGenericPassword()

AhmedFarazQaimkhani commented 2 years ago

@AlvaroBrasilia here is me get and set method Keychain.getGenericPassword({ service: serviceName, storage: Keychain.STORAGE_TYPE.RSA, accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY, accessible: Keychain.ACCESSIBLE.ALWAYS, authenticationType: Keychain.AUTHENTICATION_TYPE.BIOMETRICS, )}

Keychain.setGenericPassword(email, password, { service: serviceName, accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY, accessible: Keychain.ACCESSIBLE.ALWAYS, authenticationType: Keychain.AUTHENTICATION_TYPE.BIOMETRICS, storage: Keychain.STORAGE_TYPE.RSA, });

anhquan291 commented 2 years ago

@anhquan291 did you set sevice in Keychain.setGenericPassword() and Keychain.getGenericPassword()?

Yes, I do. The Prompt up shows again after the 2 times getting user data. It seems that on Android you just need to unlock for the first time. I atteached the video below. However the screen recorder blocked the Prompt :-( . Thank you

https://user-images.githubusercontent.com/17813202/133630343-8a0f8989-6ed8-447a-829b-80e818f814f8.mp4

jess-dovetail commented 2 years ago

This is what I have and it seems to work fine on both platforms

await Keychain.setInternetCredentials(
      SOMEID,
      email,
      password,
      {
        accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_CURRENT_SET,
        accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
      }
    );
await Keychain.getInternetCredentials(
        SOMEID,
        {
          authenticationPrompt: {
            title: I18n.t("biometrics.authenticationPrompt"),
          },
        }
      );
AlvaroBrasilia commented 2 years ago

Hello, I think we have a security issue here.

The issue is caused by

setUserAuthenticationValidityDurationSeconds()

The authentication is valid for the defined time in seconds.

If you unlock the device and click on load button when authentication time is validity the biometry modal don't show and the values are definied without a new authentication request.

Please, click to see the video below.

Watch the video

anhquan291 commented 2 years ago

I got it. It is really helpful. Thank you so much.

On Fri, 17 Sep 2021 at 21:25 Álvaro Luiz Andrade @.***> wrote:

Hello, I think we have a security issue here.

The issue is caused by

setUserAuthenticationValidityDurationSeconds() https://github.com/oblador/react-native-keychain/blob/67bee0739cabfe931cf048c409266b0be44693f3/android/src/main/java/com/oblador/keychain/cipherStorage/CipherStorageKeystoreRsaEcb.java#L229

The authentication is valid for the defined time in seconds.

If you unlock the device and click on load button when authentication time is validity the biometry modal don't show and the values are definied without a new authentication request.

Please, click to see the video below.

[image: Watch the video] https://www.youtube.com/watch?v=CmzoovDK28s

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/oblador/react-native-keychain/issues/504#issuecomment-921840529, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEH45UXJDXO35A6J6QU7NSTUCNFXNANCNFSM5D53AZNQ .

pabloearg commented 2 years ago

Hello, I think we have a security issue here.

The issue is caused by

setUserAuthenticationValidityDurationSeconds()

The authentication is valid for the defined time in seconds.

If you unlock the device and click on load button when authentication time is validity the biometry modal don't show and the values are definied without a new authentication request.

Please, click to see the video below.

Watch the video

tested on an android 9 emulator, compiled with API 30, and it didn't work

setUserAuthenticationValidityDurationSeconds() was deprecated in API 30. Maybe that's the reason why it doesn't work now?

CaioQuirinoMedeiros commented 2 years ago

Hello, I think we have a security issue here.

The issue is caused by

setUserAuthenticationValidityDurationSeconds()

I'm afraid this was a fix for another problem reported on #318. Fixed on #339 😟

KerryDss commented 2 years ago

Hi I got a question.

is it possible to change the ui of authenticationPrompt . Since my project owner give me UI design for the fingerprint.

I search the documentation but I see nothing indicating about the UI

tylim88 commented 2 years ago

I am having the same issue, the biometric(fingerprint) or pattern or whatever authentication are not working on my android phone/emulator no matter what I try, I gave up and use expo local authentication to handle the authentication part instead.

sgal commented 2 years ago

The issue here is indeed with the validity parameter on key spec. Current implementation only exposes generic API that unlocks entire Keystore if the user recently passed strong crypto challenge (passcode, Class 3 biometric, pattern, etc.).

Android has API to authorize a specific operation with Keystore, which in theory would help in this use case. But the library does not support it at the moment.

mpatafio commented 1 year ago

Probably related to this: https://github.com/oblador/react-native-keychain/issues/336#issuecomment-1192633216

saitejas-cypherd commented 1 year ago

This is what I have. Still not able to get the authentication prompt. Please kindly help me with this

await Keychain.setInternetCredentials( SOMEID, email, password, { accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_CURRENT_SET_OR_DEVICE_PASSCODE, accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY, storage: Keychain.STORAGE_TYPE.AES });

await Keychain.getInternetCredentials( SOMEID, { authenticationPrompt: { title: "", }, } );

owenadley commented 9 months ago

Has anybody been able to figure this out? I am still encountering this. I am not getting the prompt at all, although the generic password is retrieved. Works fine on iOS.

clauderobi commented 5 months ago

I am getting the prompt on Android but only if the STORAGE_TYPE is RSA. Why not AES?

progtarek commented 3 weeks ago

any update on this?