首页 > 解决方案 > BiometricPrompt Android:软件或安全更新后三星出现 UnrecoverableKeyException

问题描述

第一次在这里发帖,祝我好运:)

我们使用 BiometricPrompt API 在我们的移动应用程序中开发了对生物特征认证的支持。我们决定使用 CryptoObjects,因为它允许我们遵守法规。

实施后,我们在三星设备和一些华为设备上面临一个问题,在一些设备软件更新之后以及我们获得的几乎每个安全补丁之后:

Caused by java.security.UnrecoverableKeyException: Failed to obtain information about key
       at android.security.keystore.AndroidKeyStoreProvider.getKeyCharacteristics(AndroidKeyStoreProvider.java:238)
       at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(AndroidKeyStoreProvider.java:360)
       at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:116)
       at java.security.KeyStore.getKey(KeyStore.java:1062)
       at com.*****.mobile.data.crypto.CryptoRepositoryImpl.getSignature(CryptoRepositoryImpl.java:527)
       at com.*****.mobile.business.biometric.authentication.BiometricAuthenticationPromptInteractorImpl$getSignatureForAuthentication$1.subscribe(BiometricAuthenticationPromptInteractorImpl.java:52)

Caused by android.security.KeyStoreException: User authentication required
       at android.security.KeyStore.getKeyStoreException(KeyStore.java:1151)
       at android.security.keystore.AndroidKeyStoreProvider.getKeyCharacteristics(AndroidKeyStoreProvider.java:240)
       at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(AndroidKeyStoreProvider.java:360)
       at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:116)
       at java.security.KeyStore.getKey(KeyStore.java:1062)

这迫使我们生成一个新的密钥对,导致糟糕的用户体验。

有没有人遇到过类似的问题?并且可以建议需要更改/考虑哪些内容以防止我们的密钥在三星安全补丁后失效/损坏?

我们正在使用以下代码生成密钥对 (使用回退,因为我们发现更便宜的三星设备不支持 EC,因此我们在此类设备上使用 RSA)

@RequiresApi(Build.VERSION_CODES.M)
override fun createSigningKey(keyBaseName: KeyBaseName, useFallbackAlgorithm: Boolean): Either<Throwable, JavaPublicKey> = try {
  deleteKey(keyBaseName)
  when {
    useFallbackAlgorithm -> KeyPairGenerator
        .getInstance(KEY_ALGORITHM_RSA, ANDROID_KEY_STORE_PROVIDER)
        .apply {
          initialize(KeyGenParameterSpec.Builder(keyBaseName, PURPOSE_SIGN or PURPOSE_VERIFY)
              .setAlgorithmParameterSpec(RSAKeyGenParameterSpec(KEY_SIZE, RSAKeyGenParameterSpec.F4))
              .setDigests(DIGEST_SHA256, DIGEST_SHA512)
              .setSignaturePaddings(SIGNATURE_PADDING_RSA_PKCS1)
              .setUserAuthenticationRequired(true)
              .build())
        }
    else -> KeyPairGenerator
        .getInstance(KEY_ALGORITHM_EC, ANDROID_KEY_STORE_PROVIDER)
        .apply {
          initialize(KeyGenParameterSpec.Builder(keyBaseName, PURPOSE_SIGN or PURPOSE_VERIFY)
              .setDigests(DIGEST_SHA256, DIGEST_SHA512)
              .setUserAuthenticationRequired(true)
              .build())
        }
  }.generateKeyPair()
      .public
      .right()
} catch (e: Exception) {
  firebaseRepository.logException(RuntimeException("createSigningKey", e))
  e.left()
}

谢谢!

标签: androidsamsung-mobilebiometricsandroid-biometric-prompt

解决方案


您可以尝试实施以下 2 个解决方案,看看它是否适合您。

  1. 将 allowBackup false 添加到 AndroidManifest.xml 文件
<application
    android:allowBackup="false"
...
>
  1. Android 密钥库不是线程安全的,请使用synchronized关键字包装所有 Android 密钥库操作。

推荐阅读