0

I am trying to develop a function in my Android application that will alert me when a user changes the device fingerprint without having to call the device biometric prompt. I have attempted this using a biometric library in my code.

I only generated the secret key ,when I have open the app for the first time using below code:

if ( secretKey == null || secretKey.isDestroyed()  ){
            try {
                Log.d("tt", "900000");
                generateSecretKey(new KeyGenParameterSpec.Builder(
                        "KEY_NAME",
                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                        .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                        .setUserAuthenticationRequired(true)
                        // Invalidate the keys if the user has registered a new biometric
                        // credential, such as a new fingerprint. Can call this method only
                        // on Android 7.0 (API level 24) or higher. The variable
                        // "invalidatedByBiometricEnrollment" is true by default.
                        .setInvalidatedByBiometricEnrollment(true).setUnlockedDeviceRequired()
                        .build());
                secretKey = getSecretKey();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchProviderException e) {
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            } catch (UnrecoverableKeyException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


However, when I open the settings and change only the name of the fingerprint, it alerts me that the fingerprint has changed, even though I did not add a new fingerprint. It raised an IllegalBlockSizeException error as shown in the figure

IllegalBlockSizeException error

Tried this on a Galaxy S7 Android 8 , Can someone help me figure out how to detect actual changes to fingerprints?

   private Boolean initCipher (Cipher cipher ){
        try {
            SecretKey finalSecretKey = getSecretKey();

            cipher.init(Cipher.ENCRYPT_MODE, finalSecretKey);
            return true;
        } catch (KeyPermanentlyInvalidatedException e) {
            Log.e("invalidchanged","yesss");
            Toast.makeText(getApplicationContext(),
                    "Biometric changed", Toast.LENGTH_SHORT).show();
            return false;
        } catch (InvalidKeyException e) {
            return false;
            //throw new RuntimeException(e);
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;

    }

private void isBiometricChanged(){

        Cipher cipher = getCipher();
        SecretKey finalSecretKey = null;
        try {
            finalSecretKey = getSecretKey();
        } catch (KeyStoreException e) {
            e.printStackTrace();

        } catch (CertificateException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException e ) {
            e.printStackTrace();
        }
        // BiometricPrompt.CryptoObject(cipher);
        isBiometricChanged = !(initCipher(cipher));
        if (finalSecretKey == null ||  finalSecretKey.isDestroyed()){
            return;
        }


            if(finalSecretKey != null && !isBiometricChanged  ){
                try {
                    cipher.doFinal(
                            // plaintext-string text is whatever data the developer would like
                            // to encrypt. It happens to be plain-text in this example, but it
                            // can be anything
                            "plaintext-string".getBytes(Charset.defaultCharset()));
                   
                } catch (BadPaddingException e) {
                    Log.e("87777777777777777", "errr");
                    e.printStackTrace();
                } catch (IllegalBlockSizeException e) {
                    BiometricManager biometricManager = BiometricManager.from(this);
                    Log.e("999999999999999", "errr");

                    Log.e("ci:::", String.valueOf(cipher));
                    Log.e("ci1:::", String.valueOf(initCipher(cipher)));
                    Log.e("ci2:::", String.valueOf(finalSecretKey.toString()));
                    Log.e("ci3:::", String.valueOf(e));
                    Log.e("ci4:::", String.valueOf(isBiometricChanged));
                    Log.e("ci5:::", String.valueOf(finalSecretKey));
                    isBiometricChanged = true;
                    Toast.makeText(getApplicationContext(),
                            "changed ", Toast.LENGTH_SHORT).show();

                    e.printStackTrace();
                    //  throw new RuntimeException(e);
                } catch (InvalidKeyException e) {
                    throw new RuntimeException(e);
                }

            }
    }

private void generateSecretKey(KeyGenParameterSpec keyGenParameterSpec) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(
                KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        keyGenerator.init(keyGenParameterSpec);
        keyGenerator.generateKey();
    }
    private SecretKey getSecretKey() throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");

        // Before the keystore can be accessed, it must be loaded.
        keyStore.load(null);
        return ((SecretKey)keyStore.getKey("KEY_NAME", null));
    }


0 Answers0