codenameone / FingerprintScanner

Support for fingerprint scanning/TouchID in Codename One mobile applications
https://www.codenameone.com/
4 stars 9 forks source link

Adding Password does not work on Android API 33 #8

Open Rocketeer007 opened 1 year ago

Rocketeer007 commented 1 year ago

I have added the Fingerprint Scanner library to my Codename One project using the Maven dependency:

<dependency>
    <groupId>com.codenameone</groupId>
    <artifactId>fingerprint-scanner-lib</artifactId>
    <version>1.1.2</version>
    <type>pom</type>
</dependency>

When calling Fingerprint.addPassword(reason, key, value), the failure callback is triggered, with a very confusing exception.

D/MyAppName: [main] 0:3:46,172 - Exception: javax.crypto.IllegalBlockSizeException - null
W/System.err: javax.crypto.IllegalBlockSizeException
W/System.err:     at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:613)
W/System.err:     at javax.crypto.Cipher.doFinal(Cipher.java:2056)
W/System.err:     at com.codename1.fingerprint.impl.InternalFingerprintImpl$5$1.onAuthenticationSucceeded(InternalFingerprintImpl.java:386)
W/System.err:     at android.hardware.biometrics.BiometricPrompt$1.lambda$onAuthenticationSucceeded$0$android-hardware-biometrics-BiometricPrompt$1(BiometricPrompt.java:498)
W/System.err:     at android.hardware.biometrics.BiometricPrompt$1$$ExternalSyntheticLambda4.run(Unknown Source:4)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:942)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loopOnce(Looper.java:201)
W/System.err:     at android.os.Looper.loop(Looper.java:288)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7898)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
W/System.err: Caused by: android.security.KeyStoreException: Key user not authenticated (internal Keystore code: -26 message: In KeystoreOperation::update
W/System.err: 
W/System.err: Caused by:
W/System.err:     0: In update: KeyMint::update failed.
W/System.err:     1: Error::Km(ErrorCode(-26))) (public error code: 2 internal Keystore code: -26)
W/System.err:     at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:369)
W/System.err:     at android.security.KeyStoreOperation.handleExceptions(KeyStoreOperation.java:78)
W/System.err:     at android.security.KeyStoreOperation.update(KeyStoreOperation.java:115)
W/System.err:     at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer$MainDataStream.update(KeyStoreCryptoOperationChunkedStreamer.java:222)
W/System.err:     at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.update(KeyStoreCryptoOperationChunkedStreamer.java:156)
W/System.err:     at android.security.keystore2.KeyStoreCryptoOperationChunkedStreamer.doFinal(KeyStoreCryptoOperationChunkedStreamer.java:179)
W/System.err:     at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineDoFinal(AndroidKeyStoreCipherSpiBase.java:603)
W/System.err:   ... 12 more
D/MyAppName: [EDT] 0:3:46,220 - Exception: java.lang.RuntimeException - null
W/System.err: java.lang.RuntimeException
W/System.err:     at com.codename1.fingerprint.impl.InternalCallback.requestError(InternalCallback.java:138)
W/System.err:     at com.codename1.fingerprint.impl.InternalFingerprintImpl$5$1.onAuthenticationSucceeded(InternalFingerprintImpl.java:407)
W/System.err:     at android.hardware.biometrics.BiometricPrompt$1.lambda$onAuthenticationSucceeded$0$android-hardware-biometrics-BiometricPrompt$1(BiometricPrompt.java:498)
W/System.err:     at android.hardware.biometrics.BiometricPrompt$1$$ExternalSyntheticLambda4.run(Unknown Source:4)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:942)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loopOnce(Looper.java:201)
W/System.err:     at android.os.Looper.loop(Looper.java:288)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7898)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

Searching for other instances of this online, I found a similar issue mentioned here (https://github.com/android/security-samples/issues/86), but with no resolution.

The same application works perfectly on Android API 32

shai-almog commented 1 year ago

I have made some commits that seem to fix the issue in Git. I need to perform more thorough testing on different android versions before releasing. If all goes well, I can have a release in 7 to 10 days. But you can build from source and try it out, if you can't wait that long: https://github.com/codenameone/FingerprintScanner

shannah commented 1 year ago

With https://github.com/codenameone/FingerprintScanner/commit/8b4e57846d5705eaa5140bd72d4fa8f7469f7094 it seems to be working well now. Want more time to test on other versions. Will make release next weekend.

thinkerheart commented 1 year ago

Thank you @shannah @shai-almog for your commits about that. I saw that "setUserAuthenticationRequired" have not set on Android API 33 when keypair is generated. Could you please tell me why "setUserAuthenticationRequired" is not working on Android API 33 ? Thank you all.

Rocketeer007 commented 1 year ago

Looking at the two commits recently added here, it seems that @shai-almog tried a solution of setUserAuthenticationValidityDurationSeconds(30), and @shannah instead removed setUserAuthenticationRequired(true)

I'm not an Android developer... so I don't really understand the impact of setUserAuthenticationRequired. It would be really helpful if you could explain what this is doing, and why it's a better solution than setting a validity duration for the user authentication...

That said, I tested both solution, and for my use case, setUserAuthenticationRequired(false) seems to work better; user authentication is still required, whereas with the other solution I still got some exceptions.

Rocketeer007 commented 1 year ago

@shannah Any chance we can get a release that includes this fix?

Rocketeer007 commented 1 year ago

@shai-almog @shannah Any chance of this being released in an official version of the FingerprintScanner library?

shai-almog commented 1 year ago

I have just released this on maven central as version 1.1.3. It is also updated in the Codename One settings if you update that way.