问题描述

手机更换指纹时后,之前配合使用的密钥Cipher失效,爆出

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

然后返回给BiometricPrompt 使用时报错:

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

解决办法

对已经报错的密钥,进行删除操作:

 _keystore.deleteEntry(KEY_NAME);

而后重新获取新的密钥

   /**     * 获取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;    }

并进行初始化(关键)

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;    }

并且非常要注意的一点是, 当返回的时候, 重复执行的createCipher方法 递归, 递归返回时的结果值,第一次运行返回的是第一次执行的, 如果在retry 之后没有进行return createCipher 那么即使执行了第二次,返回的依旧是第一次的值!

有问题可随时联系QQ, 7641436

需要Android 最新X库 指纹识别(同时兼容api23&api28)并配合AndroidKetStore密钥存储的可以私聊我。

更多相关文章

  1. SE for Android(安卓)系列之整体概要(三)
  2. 第15章 Android启动过程 [Android应用开发与系统改造实战]
  3. 史上最全面解析Android事件分发机制
  4. Android(安卓)多线程-----AsyncTask详解
  5. Android(安卓)Activity之间的跳转与传值(回传)
  6. Android(安卓)Jni开发之Android(安卓)Studio中使用Android.mk
  7. Android(安卓)设置合理的定时器隔一段时间执行某段程序
  8. AndroidTouch事件的传递、拦截、消费分析
  9. Android(安卓)事件分发

随机推荐

  1. android 自定义checkbox
  2. Android(安卓)Tablayout 的使用
  3. webservice1(队列上传 呼叫)
  4. android滑动view
  5. 【Android】自定义 Tabhost
  6. Using smem on Android
  7. android五星评级
  8. android代码格式化方法小结
  9. android full screen
  10. Google Android(安卓)文档笔记-Training-