Cipher.init BiometricPrompt 成功回调中出现 UserNotAuthenticatedException 失败

Cipher.init fails with UserNotAuthenticatedException in BiometricPrompt success callback

strong text我正在为混合 Cordova 应用程序开发 Android 端。我们使用指纹保护敏感的应用程序设置(允许后备设备凭据)。此功能在插件中实现,紧跟 Android developer spec

在不修改相关代码的情况下,尽管Fingerprint对话框成功返回,但Cipher实例无法再初始化,Cipher初始化在userAuthenticationValidityDuration内(距离关闭大约有100ms) authenticationValidityDuration 设置为 3 秒的密码初始化对话框)

以下代码(通过省略所有 catch 块和嵌入小函数而略微改编)是在 @Override public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result)

中的 BiometricPrompt 中成功进行指纹认证后执行的
private void generateSecret() {
    try {
        String alias = encryptionBundle.getAlias();

        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT).setBlockModes(
                KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .setUserAuthenticationRequired(true)
                .setUserAuthenticationValidityDurationSeconds(VALIDITY_DURATION_IN_SECONDS)
                .build();

        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
                getKeyStore());
        keyGenerator.init(spec);
        keyGenerator.generateKey();
        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGORITHM);

        KeyStore keyStore = KeyStore.getInstance(getKeyStore());
        keyStore.load(null);
        SecretKey secretKey = ((SecretKey) keyStore.getKey(alias, null));

        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    ...

最后一行的 cipher.init 抛出

android.security.keystore.UserNotAuthenticatedException: User not authenticated
    at android.security.KeyStore.getInvalidKeyException(KeyStore.java:712)
    at android.security.KeyStore.getInvalidKeyException(KeyStore.java:748)
    at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
    at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:265)
    at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:109)
    at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2977)
    at javax.crypto.Cipher.tryCombinations(Cipher.java:2884)
    at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2789)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:956)
    at javax.crypto.Cipher.init(Cipher.java:1199)
   

指纹验证之前有效,我没有更改指纹插件中的任何内容。我更新了 Android Studio,自上次运行以来可能没有更改 Java 或 Gradle 版本。

我的开发环境中的哪些更改可能导致此问题?

我不知道究竟是什么导致了该行为,但我意识到该错误并未发生在其他移动设备上。

所以我删除了有问题的 phone 上的设备凭据,注册了一个新的锁屏模式和一个新的指纹,然后它又以某种方式工作了。

我在调试尝试中删除了有关有问题 phone 的加密信息,但我担心如果这个问题发生在用户 phone 上,重置设备凭据 + 指纹会使加密数据没用。