android - cipher.init 上的 Android 密钥库操作失败
问题描述
在我的 Android 应用程序中,我将一个项目插入 KeyStore,偶尔我会遇到与InvalidKeyException: Keystore operation failed
/相关的崩溃KeyStoreException: Key not found
。通常操作会成功,但总体失败率约为 10%。我认为这可能是一种竞争条件,其中 cipher.init 将在密钥创建完成之前发生,但我不确定。关于为什么此代码偶尔会失败或如何解决的任何想法?
以下是错误:
java.lang.Error: java.security.InvalidKeyException: Keystore operation failed
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1173)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.security.InvalidKeyException: Keystore operation failed
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:901)
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:926)
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:2984)
at javax.crypto.Cipher.tryCombinations(Cipher.java:2891)
at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2796)
at javax.crypto.Cipher.chooseProvider(Cipher.java:773)
at javax.crypto.Cipher.init(Cipher.java:1143)
at javax.crypto.Cipher.init(Cipher.java:1084)
at com.myapp.service.KeyStoreService.createKeysAndEncrypt(KeyStoreService.kt:32)
at com.myapp.provision.ProvisionPresenter.createKeysAndEncrypt(ProvisionRepository.kt:26)
at com.myapp.provision.ProvisionPresenter.certRetrieved(ProvisionPresenter.kt:106)
at com.myapp.provision.ProvisionPresenter.access$certRetrieved(ProvisionPresenter.kt:17)
at com.myapp.provision.ProvisionPresenter$postCompleted$1.invoke(ProvisionPresenter.kt:88)
at com.myapp.provision.ProvisionPresenter$postCompleted$1.invoke(ProvisionPresenter.kt:17)
at com.myapp.service.NetworkingService$getData$1.onResponse(NetworkingService.kt:110)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.security.KeyStoreException: Key not found
at android.security.KeyStore.getKeyStoreException(KeyStore.java:821)
这是我的代码:
val keyGenerator = KeyGenerator
.getInstance(KeyProperties.KEY_ALGORITHM_AES, context.resources.getString(R.string.key_store_instance))
val keyGenParameterSpec = KeyGenParameterSpec.Builder(alias,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()
keyGenerator.init(keyGenParameterSpec)
val secretKey = keyGenerator.generateKey()
val cipher = Cipher.getInstance(context.resources.getString(R.string.key_store_transformation))
//This is where the crash occurs
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val iv = cipher.iv
val byteCert = cert.toByteArray()
val encryption = cipher.doFinal(byteCert)
解决方案
推荐阅读
- laravel - Laravel 规则验证两个变量
- language-agnostic - 使用 while 循环的简单示例
- relational-database - laravel5.6中的任何其他方法而不是关系?
- regex - 正则表达式是否包含恰好出现两次“aa”的所有字符串?
- python - 在 pytorch 中训练模型时出现运行时错误
- angular - Angular:我可以从服务中获取对象,但似乎我没有正确分配对象
- java - 运行 Selenium 时出现空指针异常 - 使用 pagefactory 的 TestNG 脚本
- wordpress - 如何在 wordpress 中正确设置永久链接?
- matlab - 从MATLAB中的单个矩阵中提取多个矩阵
- scala - 为什么在 spark scala 中使用 inferSchema 的选项为 true 时数据类型错误?