新增生物特征未使密钥失效,Android密钥创建实现是否有误?
问题分析与解决
你的实现问题出在密钥的创建时机,以及对setInvalidatedByBiometricEnrollment(true)作用的实际触发逻辑理解偏差:
核心问题
你在BiometricPrompt的onAuthenticationSucceeded回调里调用createKey(),这意味着每次用户生物识别验证成功后,都会生成一个同名的新密钥,直接覆盖旧密钥。而setInvalidatedByBiometricEnrollment(true)的作用是:当用户新增/删除/更新生物特征(比如指纹)时,已存在的密钥会被标记为无效,但因为你每次验证成功都立刻生成新密钥覆盖旧的,导致旧密钥失效的场景根本不会被触发——新密钥是在生物特征变更后创建的,自然不受之前的变更影响,也就无法强制用户重新输入凭据。
修正方案
1. 调整密钥创建时机
不要在每次生物识别成功后创建密钥,而是仅在以下场景调用createKey():
- 首次启用生物识别功能时
- 检测到旧密钥因生物特征变更失效(捕获
KeyPermanentlyInvalidatedException),且用户通过了密码/PIN等强凭据验证后
2. 新增密钥获取逻辑
使用密钥前先尝试从KeyStore中获取已存在的密钥,判断是否有效:
fun getKey(): SecretKey? { val androidKeyStore = "AndroidKeyStore" val keyName = "my_key" return try { val keyStore = KeyStore.getInstance(androidKeyStore) keyStore.load(null) keyStore.getKey(keyName, null) as? SecretKey } catch (e: Exception) { when (e) { is KeyPermanentlyInvalidatedException -> { // 密钥因生物特征变更失效,返回null触发重新验证流程 null } else -> { logger.log(Level.FINEST, e.message, e) null } } } }
3. 修正验证与密钥使用流程
// 当需要使用生物识别加密/解密时 val existingKey = getKey() if (existingKey == null) { // 密钥失效或不存在,强制用户输入密码/PIN等强凭据 showPasswordPrompt { isAuthenticated -> if (isAuthenticated) { // 验证通过后创建新密钥 createKey() // 继续后续业务逻辑 } } } else { // 使用有效密钥进行操作 performEncryption(existingKey) }
4. 保留原createKey()的核心配置
你的createKey()方法中setInvalidatedByBiometricEnrollment(true)、setUserAuthenticationParameters(0, KeyProperties.AUTH_BIOMETRIC_STRONG)这些配置是正确的,不需要修改——只要调整调用时机即可生效。
内容的提问来源于stack exchange,提问作者andrewedgar
相关产品推荐
相关产品推荐

