oblador / react-native-keychain

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

getGenericPassword not prompting biometrics #244

Open hansyulian opened 4 years ago

hansyulian commented 4 years ago

This is my settings on set password:

  private async setPassword() {
    const username = 'this is the username';
    const password = 'this is the pin';
    await KeyChain.setGenericPassword(username, password, {
      accessControl: KeyChain.ACCESS_CONTROL.BIOMETRY_ANY,
      accessible: KeyChain.ACCESSIBLE.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY,
    });
    console.warn('password set');
  }

and this is the get password:


  private async retrievePassword() {
    try {
      // Retrieve the credentials
      const credentials = await KeyChain.getGenericPassword();
      if (credentials) {
        console.warn('Credentials successfully loaded for user ' + credentials.username, credentials.password);
      } else {
        console.warn('No credentials stored');
      }
    } catch (error) {
      console.warn('Keychain couldn\'t be accessed!', error);
    }
  }

and the render:


  public render(): ReactNode {
    const { biometricType } = this.state;
    return (
      <DefaultLayout>
        <View style={[commonStyles.padding1Base]}>
          <Text>{biometricType}</Text>
        </View>
        <View style={[commonStyles.padding1Base]}>

          <Button onPress={() => this.setPassword()}>Set Pass</Button>
        </View>
        <View style={[commonStyles.padding1Base]}>
          <Button onPress={() => this.retrievePassword()}>Try get</Button>
        </View>
      </DefaultLayout>
    );
  }

The biometric type is showing "fingerprint", set seems working fine, but when try to get it, it just get right away without prompting any fingerprint.

I tested this in Samsung Galaxy Note 8

ddizh commented 4 years ago

Try to change your app bundle id and re-deploy to device or reset privacy settings. It happened to me because I once rejected keychain access permissions request.

hansyulian commented 4 years ago

weird, it still doesn't work, but i tried the https://www.npmjs.com/package/react-native-biometrics, it asking for fingerprint right away. any clue?

hansyulian commented 4 years ago

actually is there a way to force authentication, like pin or biometrics when we getting? something like:

 const credentials = await KeyChain.getGenericPassword({
    forceAuth: true
 });
hansyulian commented 4 years ago

wait, i just realized that those options only for iOS only, how about the android?

Volksfeld commented 4 years ago

I'm wondering about the same thing... iOS works fine, but android doesn't prompt for biometrics, or setGenericPassword breaks on android when passing iOS params.

raldred commented 4 years ago

Getting the same behaviour on iOS, not prompt for biometrics getGenericPassword always returns false evening after set work successfully. iOS 13.

Volksfeld commented 4 years ago

@raldred. Got the same behaviour, I've managed to fix this way:

 await setGenericPassword( email, password {
        service: 'service',
        accessControl: 'BiometryAny',
        accessible: 'AccessibleWhenPasscodeSetThisDeviceOnly',
      },
      );

But this creates another problem: Android will set the password, but wont actually store it. Also, are you on simulator or device? iOS 13 simulator + new XCode are pretty broken

aeirola commented 4 years ago

As @hansyulian correctly pointed out, the documentation mentions that accessControl option is for iOS only. The library doesn't support fingerprint authentication for Android at the moment. There is work being done to add this functionality, but the implementation is not yet complete.

On iOS the biometric authentication prompt won't be visible when running in a simulator. This is due to the behaviour or the iOS simulator, as mentioned in https://github.com/oblador/react-native-keychain/issues/111#issuecomment-370036274

taschik commented 4 years ago

any update on this?

geekShivam commented 4 years ago

@aeirola Do we have any ETA for the fingerprint authentication in android?

aeirola commented 4 years ago

@geekShivam Unfortunately I don't have any more more information about the progress than the recent discussions in the latest PR #260

OleksandrKucherenko commented 4 years ago

https://github.com/oblador/react-native-keychain/pull/260 - is ready for merge... every LIKE and comment will make it more close to release. follow the PR... I hope it will be merged in several hours.

Danondso commented 3 years ago

Did this get implemented? Testing on my nexus 6P has me not getting prompted subsequent times πŸ€”

hassan74-98 commented 3 years ago

πŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈThe trick is so simple You just have to define 'storage type' as rsa. (by default it's aes) Example await KeyChain.setGenericPassword(username, password, { accessControl: KeyChain.ACCESS_CONTROL.BIOMETRY_ANY, accessible: KeyChain.ACCESSIBLE.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY, storage : Keychain. STORAGE_TYPE.RSA }); πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰ I just downloaded the "KeychainExample" and then figured out the solution

nicholascm commented 3 years ago

I found that it required me to set the service name On emulator with Google Pixel 3A - using @hassan74-98 solution didn't work for me without that on this device...


    const appBundleId = await DeviceInfo.getBundleId(); // only used for android as default for service on iOS is bundleId

   // can leave iOS as undefined as it appears this library defaults iOS to package name

   await Keychain.setGenericPassword(KEYCHAIN_KEY, 'password', {
      service: Platform.OS === 'ios' ? undefined : appBundleId,
      accessControl: Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE,
      accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
    });
tristanheilman commented 1 year ago

πŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈπŸ€¦β€β™‚οΈThe trick is so simple You just have to define 'storage type' as rsa. (by default it's aes) Example await KeyChain.setGenericPassword(username, password, { accessControl: KeyChain.ACCESS_CONTROL.BIOMETRY_ANY, accessible: KeyChain.ACCESSIBLE.WHEN_PASSCODE_SET_THIS_DEVICE_ONLY, storage : Keychain. STORAGE_TYPE.RSA }); πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰ I just downloaded the "KeychainExample" and then figured out the solution

Why did this work.. I need an explanation.