Git Product home page Git Product logo

codenameone / fingerprintscanner Goto Github PK

View Code? Open in Web Editor NEW
4.0 5.0 9.0 463 KB

Support for fingerprint scanning/TouchID in Codename One mobile applications

Home Page: https://www.codenameone.com/

Java 83.67% Objective-C 12.37% JavaScript 1.06% C# 0.62% Shell 2.15% CSS 0.14%
codenameone android-library ios touchid fingerprint fingerprint-sensor fingerprint-validation authentication biometrics

fingerprintscanner's Introduction

Fingerprint Scanner

Fingerprint scanning and biometric support for Codename One.

fingerprint scanner feature

This cn1lib provides basic support for fingerprint scanning on iOS/Android with one API. Due to the difference between the two implementations we chose a simplified approach that just verifies the fingerprint and doesn’t delve into the nuanced complexities for this API.

Supported Platforms

Currently this library supports only Android (API 23+), and iOS.

Installation

For instructions on installing cn1libs, see this tutorial.

Alternate Maven Installation

If your project uses Maven, the above installation instructions will still work, but you can alternately simply add the Maven dependency to your common/pom.xml file:

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

Android builds must use build tools 29 or higher. E.g. Add the following build hints:

android.buildToolsVersion=29.0.3
android.targetSdkVersion=29.0.3

Basic Usage

Fingerprint.scanFingerprint("Use your finger print to unlock AppName.", value -> {
    Log.p("Scan successfull!");
}, (sender, err, errorCode, errorMessage) -> {
    Log.p("Scan Failed!");
});

Note that the values passed to value/fail are null and don’t include any data at this time…​

Also check out the following samples:

  1. FingerprintScannerTest App - Basic usage. Just fingerprint scanning.

  2. FingerprintScannerSample - From Codename One samples. Includes sample of storing, retrieving, and deleting passwords.

Protecting Passwords with Fingerprints

This library also allows you to store passwords in the system keychain, protected by biometric authentication. The user will be asked to authenticate with their fingerprint (or Face recognition on supported devices) in order to retrieve passwords using this library. On Android, currently the user is also prompted to authenticate when storing passwords as well.

Note
While these methods say that they are for storing passwords, you can use them for storing any text. Both Android and iOS should allow you to store strings of sufficiently large size to store anything you might otherwise store in Preferences.

Storing Passwords

String account = "[email protected]";
String password = "....";

Fingerprint.addPassword(
    "Adding secure item to keystore", // Message to display in authentication dialog
    account,
    password
).onResult((success, err)->{
    if (err != null) {
        Log.e(err);
        ToastBar.showErrorMessage("Failed to add password to keystore: "+ err.getMessage());
    } else {
        // success always true if there was no error.
        ToastBar.showInfoMessage("Successfully added password to keystore");
    }
});

Retrieving Passwords

String account = "[email protected]";

Fingerprint.getPassword(
    "Getting secure item",  // Message to display in auth dialog
    account
).onResult((password, err)->{
    if (err != null) {
        // Error condition occurs both if the keychain doesn't have
        // a password for the given account, or if a failure occurs
        // in retrieving it.
        // NOTE:  If the user adds a finger or face to biometric scanning
        // or disables password protection on the device, all passwords
        // will be purged automatically.
        Log.e(err);
        ToastBar.showErrorMessage("Failed to get password: " + err.getMessage());
    } else {
        System.out.println("The password was "+password);
    }
});

Deleting Passwords

String account = "[email protected]";

Fingerprint.deletePassword(
    "Getting secure item",   // Message to display in auth dialog
    keyName.getText()
).onResult((res, err)->{
    if (err != null) {
        Log.e(err);
        ToastBar.showErrorMessage("Failed to delete password: "+err.getMessage());
    } else {
        System.out.println("Deleted the password for account "+account);
    }
});

Password Invalidation

Passwords stored in the keychain will be automatically purged if any of the following occurs:

  1. The user adds additional fingers to fingerprint authentication.

  2. The user adds additional faces to face ID biometric authentication.

  3. The user turns off phone login security. E.g. if they turn off password or fingerprint requirements for login to the phone.

Android Implementation

Currently, on Android we are using the FingerprintManager class for authentication on API 28 (Android 9) and lower and BiometricPrompt on devices running API 29 (Android 10) and higher. This means that Android 9, despite supporting Face recognition at an OS level, will use FingerPrintManager and will not support face recognition for authentication. Future versions may attempt to incorporate workarounds to add this support to Android 9, e.g. AdvancedBiometricPromptCompat.

Passwords are not, themselves, stored inside the system Keystore. Rather, a symmetric Key is generated and stored inside the keychain, which is used to encrypt and decrypt the passwords, which are stored private SharedPreferences.

Currently the key specifications are:

new KeyGenParameterSpec.Builder(
    KEY_ID,
    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)

Refer to the KeyGenParameterSpec.Builder docs for a more detailed description of what these settings mean.

The .setUserAuthenticationRequired(true) call is what causes the key to become invalid when the user adds fingers or faces to authentication.

iOS Implementation

On iOS, the library acts as a thin layer on top of the SecItemAdd, SecItemCopyMatching, and SecItemDelete functions which directly add passwords to the keychain.

The security settings on the passwords are:

SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
    kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
    kSecAccessControlTouchIDCurrentSet,
    nil
);

For more details on what these mean, see the following documentation pages:

Working with the Sources

  1. Check out with git clone https://github.com/codenameone/FingerprintScanner

  2. Build with mvn package

    1. You’ll find cn1lib in the common/target directory.

See the Codename One Maven Manual for more information about working with Codename One Maven projects.

Releasing to Maven Central

  1. Set up your ~/.m2/settings.xml file with credentials for Maven central.

  2. Run bash update-version.sh $NEW_VERSION where $NEW_VERSION is the new version. E.g. "1.1".

  3. git push && git push --tags to push the new version tag to git.

  4. mvn deploy -Psign-artifacts

  5. Log into Maven central and complete the release.

  6. Run bash update-version $NEW_SNAPSHOT_VERSION where $NEW_SNAPSHOT_VERSION is the next snapshot version E.g. 1.2-SNAPSHOT.

fingerprintscanner's People

Contributors

dependabot[bot] avatar diamondobama avatar shai-almog avatar shannah avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

fingerprintscanner's Issues

Adding Password does not work on Android API 33

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 (android/security-samples#86), but with no resolution.

The same application works perfectly on Android API 32

Android Dialog flickers on-screen when reattempting fingerprint scan following a fingerprint scan failure callback

Hi,

Thanks for such a great library.

I am testing code to see how it handles invalid fingerprints and then correct fingerprints.

I am using setting the showDialogOnAndroid variable to true, which is working nicely. After scanning an invalid fingerprint, the failure callback occurs as it should but then, when trying to authenticate again -- calling the same Fingerprint.scan() method with showDialogOnAndroid set to true -- the Dialog flickers on screen. I can still scan my fingerprint, but I'm concerned that users may miss the Dialog altogether as it shows and disappears so quickly and won't know that the scanner is ready to validate fingerprints.

Can you please advise?

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.