authpass / biometric_storage

Flutter plugin to store data behind biometric authentication (ie. fingerprint)
https://pub.dev/packages/biometric_storage
MIT License
171 stars 101 forks source link

Exception when using pre release version - 3.0.0-rc.6 #35

Closed Androrier closed 2 years ago

Androrier commented 2 years ago

I/flutter (25078): login error: PlatformException(Unexpected Error, User not authenticated, android.security.keystore.UserNotAuthenticatedException: User not authenticated I/flutter (25078): android.security.keystore.UserNotAuthenticatedException: User not authenticated I/flutter (25078): at android.security.KeyStore.getInvalidKeyException(KeyStore.java:1497) I/flutter (25078): at android.security.KeyStore.getInvalidKeyException(KeyStore.java:1539) I/flutter (25078): at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54) I/flutter (25078): at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89) I/flutter (25078): at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:265) I/flutter (25078): at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:109) I/flutter (25078): at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2984) I/flutter (25078): at javax.crypto.Cipher.tryCombinations(Cipher.java:2891) I/flutter (25078): at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2796) I/flutter (25078): at javax.crypto.Cipher.chooseProvider(Cipher.java:773) I/flutter (25078): at javax.crypto.Cipher.init(Cipher.java:1143) I/flutter (25078): at javax.crypto.Cipher.init(Cipher.java:1084) I/flutter (25078): at design.codeux.biometric_storage.CryptographyManagerImpl.getInitializedCipherForEncryption(CryptographyManager.kt:94) I/flutter (25078): at design.codeux.biometric_storage.BiometricStorageFile.cipherForEncrypt(BiometricStorageFile.kt:68) I/flutter (25078): at design.codeux.biometric_storage.BiometricStoragePlugin$onMethodCall$4.invoke(BiometricStoragePlugin.kt:154) I/flutter (25078): at design.codeux.biometric_storage.BiometricStoragePlugin$onMethodCall$8.invoke(BiometricStoragePlugin.kt:198) I/flutter (25078): at design.codeux.biometric_storage.BiometricStoragePlugin$onMethodCall$8.invoke(BiometricStoragePlugin.kt:88) I/flutter (25078): at design.codeux.biometric_storage.BiometricStoragePlugin$onMethodCall$3.invoke(BiometricStoragePlugin.kt:146) I/flutter (25078): at design.codeux.biometric_storage.BiometricStoragePlugin.onMethodCall(BiometricStoragePlugin.kt:198) I/flutter (25078): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233) I/flutter (25078): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85) I/flutter (25078): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818) I/flutter (25078): at android.os.MessageQueue.nativePollOnce(Native Method) I/flutter (25078): at android.os.MessageQueue.next(MessageQueue.java:335) I/flutter (25078): at android.os.Looper.loop(Looper.java:206) I/flutter (25078): at android.app.ActivityThread.main(ActivityThread.java:8528) I/flutter (25078): at java.lang.reflect.Method.invoke(Native Method) I/flutter (25078): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) I/flutter (25078): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) I/flutter (25078): , null) - stack: #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:597:7) I/flutter (25078): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)

hpoul commented 2 years ago

which options did you use? which android version? which device? how did you authenticate? is it reproducible with the example/?

Androrier commented 2 years ago

Used the same code with the example. Happend on Samsung galaxy A12, Android 11 Pixel 3a, Android 11.

The same code worked on previous version 2.0.3

Androrier commented 2 years ago

Maybe this can help you? https://github.com/googlearchive/android-FingerprintDialog/issues/41#issuecomment-515704555

If you need any help, don't hesitate to reach out.

Androrier commented 2 years ago

https://youtu.be/osNYxH1aaTM

hpoul commented 2 years ago

If you need any help, don't hesitate to reach out.

feel free to create a PR if you've get time before me 🤷‍♂️️

hpoul commented 2 years ago

according to that link, you might want to try to just pass in -1 as authenticationValidityDurationSeconds .. strange though that i didn't see that error.. but it makes kind of sense..

Androrier commented 2 years ago

Tried passing -1, still the same result But regarding This issue Is it possible to avoid authentication when deleting? (Only authenticate when reading + writing) Or this should be a feature request?

Androrier commented 2 years ago

Check this out:

E/flutter (15575): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: PlatformException(Unexpected Error, per-operation authentication is not supported (UserAuthenticationValidityDurationSeconds must be >0), java.lang.IllegalArgumentException: per-operation authentication is not supported (UserAuthenticationValidityDurationSeconds must be >0) E/flutter (15575): java.lang.IllegalArgumentException: per-operation authentication is not supported (UserAuthenticationValidityDurationSeconds must be >0) E/flutter (15575): at androidx.security.crypto.MasterKeys.validate(MasterKeys.java:128) E/flutter (15575): at androidx.security.crypto.MasterKeys.getOrCreate(MasterKeys.java:95) E/flutter (15575): at androidx.security.crypto.MasterKey$Builder.buildOnM(MasterKey.java:357) E/flutter (15575): at androidx.security.crypto.MasterKey$Builder.build(MasterKey.java:314) E/flutter (15575): at design.codeux.biometric_storage.BiometricStorageFile.(BiometricStorageFile.kt:56) E/flutter (15575): at design.codeux.biometric_storage.BiometricStoragePlugin.onMethodCall(BiometricStoragePlugin.kt:189) E/flutter (15575): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233) E/flutter (15575): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85) E/flutter (15575): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818) E/flutter (15575): at android.os.MessageQueue.nativePollOnce(Native Method) E/flutter (15575): at android.os.MessageQueue.next(MessageQueue.java:335) E/flutter (15575): at android.os.Looper.loop(Looper.java:206) E/flutter (15575): at android.app.ActivityThread.main(ActivityThread.java:8528) E/flutter (15575): at java.lang.reflect.Method.invoke(Native Method) E/flutter (15575): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) E/flutter (15575): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) E/flutter (15575): , null) E/flutter (15575): #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:597:7) E/flutter (15575): #1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18) E/flutter (15575): E/flutter (15575): #2 MethodChannelBiometricStorage.getStorage (package:biometric_storage/src/biometric_storage.dart:309:22)

hpoul commented 2 years ago

ups.. yeah.. that's the "compatibility" mode which still uses the androidx.security stuff.. I should probably either remove it or at least initialize it lazily.. that needs both fixing.. (not passing cryptoObject when having validity duration >= 0 and removing androidx.security or workaround that problem)..

Androrier commented 2 years ago

OK, sounds cool, keep us posted. Any updates regarding deleting the storage without biometric?

hpoul commented 2 years ago

fyi, i've just published 3.0.0-rc.7 .. it should now work also with authenticationValidityDurationSeconds > -1 .. but i've now also changed the default value for authenticationValidityDurationSeconds to -1 .. imho this would be the most clear way.. I've only not used it before because androidx.security didn't support it.. My hope is, that this is the most stable version of this annoying API.. imho the android KeyStore APIs are pretty broken.. If you still get 'user not authenticated' errors, try to delete it.. afterwards it always worked for me. I didn't yet quite figure out when it breaks though.

I guess it will also break when the authenticationValidityDurationSeconds of an existing Key changes.. so i guess once it is created with a setting, it's not a good idea to ever change that.