2

I am using Fingerprint sensor in my application. I know that api is available for marshmallow and above OS. So while running in my class I am checking dynamically for sdk version.

Even the code for fingerprint not execution I am facing following exception on 4.0 android os, while the same executes for 5.0 and above.

**java.lang.VerifyError: com/cloudzon/gratzeez1/GiveGratuityActivity
                                                                        at java.lang.Class.newInstanceImpl(Native Method)
                                                                        at java.lang.Class.newInstance(Class.java:1215)
                                                                        at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2265)
                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
                                                                        at android.app.ActivityThread.access$800(ActivityThread.java:151)
                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
                                                                        at android.os.Handler.dispatchMessage(Handler.java:110)
                                                                        at android.os.Looper.loop(Looper.java:193)
                                                                        at android.app.ActivityThread.main(ActivityThread.java:5322)
                                                                        at java.lang.reflect.Method.invokeNative(Native Method)
                                                                        at java.lang.reflect.Method.invoke(Method.java:515)
                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
                                                                        at dalvik.system.NativeStart.main(Native Method)**

I found that because of following code in my class I am facing this issue.

public boolean cipherInit() {
    try {
        cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        throw new RuntimeException("Failed to get Cipher", e);
    }

    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);
    }
}
Jay Vyas
  • 2,674
  • 5
  • 27
  • 58

2 Answers2

7

I ran into this as well and another answer got me on the right track; How to Use Unsupported Exception for Lower Platform Version

I change that method to;

public boolean cipherInit() {
    try {
        cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        throw new RuntimeException("Failed to get Cipher", e);
    }

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

Changing the catch block for KeyPermanentlyInvalidatedException from (KeyPermanentlyInvalidatedException e) to (e instanceof KeyPermanentlyInvalidatedException) seemed to fix the issue for some reason.

Community
  • 1
  • 1
opt05
  • 813
  • 11
  • 21
  • coming across this error for the first time. no one seems to have an answer for it on here.im getting it in my application module when creating a new instance of a class – filthy_wizard Mar 27 '17 at 10:15
  • If your error isn't related to adding Cipher and/or Fingerprint code to your Android project, then I suggest you open a new question. – opt05 Mar 27 '17 at 13:38
2

I simply solve it by changing the catch exception block. The KeyPermanentlyInvalidatedException is a subclass of InvalidKeyException and if we use the KeyPermanentlyInvalidatedException we got the VerifyError.

catch (KeyPermanentlyInvalidatedException e) {
(...)
}

Instead, use InvalidKeyException

catch (InvalidKeyException e) {
(...)
}

@opt05 answer help me to solve my problem, but I didn't like his approach using the instance of.

Pedro Romão
  • 2,285
  • 28
  • 22
  • +1 for advocating against `instanceof`. It has uses and although Android is already one hell of a mess, there are usually better solutions – Kaiser Keister May 14 '20 at 11:42