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 上,重置设备凭据 + 指纹会使加密数据没用。
strong text我正在为混合 Cordova 应用程序开发 Android 端。我们使用指纹保护敏感的应用程序设置(允许后备设备凭据)。此功能在插件中实现,紧跟 Android developer spec
在不修改相关代码的情况下,尽管Fingerprint对话框成功返回,但Cipher实例无法再初始化,Cipher初始化在userAuthenticationValidityDuration
内(距离关闭大约有100ms) authenticationValidityDuration 设置为 3 秒的密码初始化对话框)
以下代码(通过省略所有 catch 块和嵌入小函数而略微改编)是在 @Override public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result)
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 上,重置设备凭据 + 指纹会使加密数据没用。