前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android X库 BiometricPrompt 中 Crypto primitive not initialized 问题研究

Android X库 BiometricPrompt 中 Crypto primitive not initialized 问题研究

作者头像
胖虎哥
发布2023-05-10 19:21:11
3220
发布2023-05-10 19:21:11
举报

问题描述

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

代码语言:javascript
复制
		Key permanently invalidated  (该密钥已被永久无效)错误

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

代码语言:javascript
复制
	Caused by: java.lang.IllegalStateException: Crypto primitive not initialized

解决办法

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

代码语言:javascript
复制
 _keystore.deleteEntry(KEY_NAME);

而后重新获取新的密钥

代码语言:javascript
复制
   /**
     * 获取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;
    }

并进行初始化(关键)

代码语言:javascript
复制
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 那么即使执行了第二次,返回的依旧是第一次的值!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 解决办法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档