Research on Crypto primitive not initialized problem in Android X library BiometricPrompt

Problem Description

After changing the fingerprint on the mobile phone , the previously used key Cipher becomes invalid, and the

		Key permanently invalidated  (该密钥已被永久无效)错误

Then return to BiometricPrompt and report an error:

	Caused by: java.lang.IllegalStateException: Crypto primitive not initialized

Solution

Delete the key that has been reported as an error:

 _keystore.deleteEntry(KEY_NAME);

Then get a new key again

   /**
     * 获取key
     */
  Key GetKey() throws Exception {
    
    

        Key secretKey;

        if (!_keystore.isKeyEntry(KEY_NAME)) {
    
    
           return CreateKey();
        }
        secretKey = _keystore.getKey(KEY_NAME, null);
        return secretKey;
    }
    
    /**
     * 创建key
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    Key CreateKey() throws Exception {
    
    

        Log.e(TAG, "CreateKey ");
        KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHM, KEYSTORE_NAME);
        KeyGenParameterSpec keyGenSpec =
                new KeyGenParameterSpec.Builder(KEY_NAME,
                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                        .setBlockModes(BLOCK_MODE)
                        .setEncryptionPaddings(ENCRYPTION_PADDING)
                        .setUserAuthenticationRequired(true)
                        .build();
        keyGen.init(keyGenSpec);
        SecretKey secretKey = keyGen.generateKey();

        return secretKey;
    }

and initialize (key)

Cipher createCipher(boolean retry, int operMode, byte[] iv) throws Exception {
    
    
        Key key = GetKey();
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        try {
    
    
            if (operMode == Cipher.ENCRYPT_MODE) {
    
    
                cipher.init(Cipher.ENCRYPT_MODE, key);
            } else if (operMode == Cipher.DECRYPT_MODE) {
    
    
                IvParameterSpec ivSpec = new IvParameterSpec(iv);
                cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
            }
        } catch (KeyPermanentlyInvalidatedException e) {
    
    
            // 该密钥已被永久无效 Key permanently invalidated
            Log.e(TAG, "createCipher: "+e.getMessage() );
            _keystore.deleteEntry(KEY_NAME);
            if (retry) {
    
    
                 return createCipher(false, operMode, iv);
            } else {
    
    
                throw new Exception("Could not create the cipher for fingerprint authentication.", e);
            }
        }
        return cipher;
    }

And it is very important to note that when returning, the repeatedly executed createCipher method recurses, and the result value when recursively returns, the first run returns the first execution, if return createCipher is not performed after retry, then even Executed for the second time, the returned value is still the first time!

If you have any questions, please feel free to contact QQ, 7641436

If you need the latest Android X library fingerprint recognition (compatible with api23&api28) and AndroidKetStore key storage, you can chat with me privately.

Guess you like

Origin blog.csdn.net/a_Chaon/article/details/106525023