Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android fingerprint on SDK<23

I have a project on Android with minSDK=17 and targetSDK=23. We have a fingerprint authentication in this project made using FingerprintManager class (it was added in SDK23). We added SDK version check, so we are not using anything related to fingerprint if SDK<23. But in older SDK versions app behaviour is unpredictable: on some versions app just crashing, on other -- fingerprint not working (so, it's ok).

My question:

1) Is it any good and easy-to-implement libraries for minSDK=17, that can recognize fingerprints? 2) How can I avoid app crashing in devices with SDK<23? Crash error:

E/dalvikvm: Could not find class 'android.hardware.fingerprint.FingerprintManager', referenced from method nl.intratuin.LoginActivity.loginByFingerprint
E/AndroidRuntime: FATAL EXCEPTION: main   java.lang.VerifyError:
LoginActivity at java.lang.Class.newInstanceImpl(Native Method)

Some new info: created HelloWorld fingerprint project using this tutorial: http://www.techotopia.com/index.php/An_Android_Fingerprint_Authentication_Tutorial Found the root of the problem: FingerprintDemoActivity->cipherInit:

try {
    keyStore.load(null);
    SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
             null);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return true;
} catch (KeyPermanentlyInvalidatedException e) {
    return false;
} catch (KeyStoreException | CertificateException 
      | UnrecoverableKeyException | IOException
      | NoSuchAlgorithmException | InvalidKeyException e) {
   throw new RuntimeException("Failed to init Cipher", e);
}

First catch block breacking whole app with error I mentioned above. Of course, I can just remove this catch (this exception extends InvalidKeyException, so it will be handled), and return false in case of any exceptions. Is it any better way?

like image 307
Ivan Budnikov Avatar asked Nov 29 '22 01:11

Ivan Budnikov


2 Answers

I think, I found acceptable solution: catch not KeyPermanentlyInvalidatedException, but InvalidKeyException. Everything working fine this way. Still have no idea how this exception crashed whole app...

like image 56
Ivan Budnikov Avatar answered Dec 12 '22 14:12

Ivan Budnikov


It happened to me also..even when i used : if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M).. my app crashes on android 4.4- kitkat. so eventually the problem was in the initCipher method in the catches part - see the following code (even though i m not suppose to get there as it targeted to M and above... very strange behaviour..) :

@TargetApi(Build.VERSION_CODES.M)
private boolean initCipher() {
    try {
        mKeyStore.load(null);
        SecretKey key = (SecretKey) mKeyStore.getKey(KEY_NAME, null);
        mCipher.init(Cipher.ENCRYPT_MODE, key);

        return true;
    } catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
            | NoSuchAlgorithmException e) {
        throw new RuntimeException("Failed to init Cipher", e);
    } catch (InvalidKeyException e) {
        e.printStackTrace();
        return false;

    }
}

apparently the order off the catches matter..so just make sure to write it as i mentioned.

like image 34
Hilit Avatar answered Dec 12 '22 14:12

Hilit