UnrecoverableKeyException无法获取有关私钥的信息,KeyStoreException:无效的密钥blob

问题描述 投票:16回答:1

在我们的应用中,我们一直无法访问Android Keystore中的数据问题。我们看到的特定异常在这里:

java.security.UnrecoverableKeyException: Failed to obtain information about private key
 at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:223)
 at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:259)
 at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(AndroidKeyStoreProvider.java:269)
 at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:94)
 at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:474)
 at java.security.KeyStore.getEntry(KeyStore.java:1560)
 at <PACKAGE_NAME>.EncryptionInteractor.generateKeys(EncryptionInteractor.java:104)
 at <PACKAGE_NAME>.EncryptionInteractor.generateKeys(EncryptionInteractor.java:100)
 at <PACKAGE_NAME>.EncryptionInteractor.init(EncryptionInteractor.java:93)
 at <PACKAGE_NAME>.EncryptionInteractor.<init>(EncryptionInteractor.java:80)
 at <PACKAGE_NAME>.EncryptionInteractor.init(EncryptionInteractor.java:65)
 at <PACKAGE_NAME>.<APPLICATION_CLASS>.onCreate(APPLICATION_CLASS.java:17)
 at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1118)
 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5791)
 at android.app.ActivityThread.-wrap1(Unknown Source:0)
 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1661)
 at android.os.Handler.dispatchMessage(Handler.java:105)
 at android.os.Looper.loop(Looper.java:164)
 at android.app.ActivityThread.main(ActivityThread.java:6541)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: android.security.KeyStoreException: Invalid key blob
 at android.security.KeyStore.getKeyStoreException(KeyStore.java:695)
 at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:224)
  ... 21 more

我们还无法提出可靠的方法来重现此问题。一些文章提到了可能导致密钥库“忘记”密钥或被锁定的可能状态,例如here。但是,据我所知,我们还没有陷入任何这些极端情况。首次设置密钥后,让设备静置一会儿似乎会发生这种情况。我们已经看到这种情况发生在21至26的多个仿真器和设备上。此外,这些设备都使用了滑动解锁或PIN。更改PIN或安全方法似乎不会导致此问题。同样,在设备闲置几天后似乎还会出现此问题。

我发现了另外两个SO herehere以及一个Google issue。如果我理解正确,则两者中链接的答案似乎都取决于前提:调用者在创建Key时已调用[C​​0],而我们尚未这样做。另外,给定的解决方案似乎仅依赖于删除密钥并生成一个新密钥。

下面是我们为>> API 23版本设置的密钥的设置。由于我们主要是在>> 23 APIs上看到的,因此我们省略了23之前版本的密钥生成。

setUserAuthenticationValidityDurationSeconds

然后,我们稍后尝试通过private static final int RSA_KEY_SIZE = 2048; private static final String CERT_SUBJECT_STRING = "CN=<COMPANY_NAME> Android App O=<COMPANY_NAME>"; private static final String ANDROID_KEY_STORE = "AndroidKeyStore"; try { String alias = KEY_NAME; KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEY_STORE); Calendar start = Calendar.getInstance(); Calendar end = Calendar.getInstance(); end.add(Calendar.YEAR, 1); KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setAlgorithmParameterSpec(new RSAKeyGenParameterSpec(RSA_KEY_SIZE, RSAKeyGenParameterSpec.F4)) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) .setBlockModes(KeyProperties.BLOCK_MODE_ECB) .setCertificateNotAfter(end.getTime()) .setCertificateNotBefore(start.getTime()) .setCertificateSerialNumber(BigInteger.ONE) .setCertificateSubject(new X500Principal(CERT_SUBJECT_STRING)) .build(); generator.initialize(spec); generator.generateKeyPair(); } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) { e.printStackTrace(); } 访问密钥。再次,这可以工作一段时间,但随后将开始引发上述异常。

android private-key android-keystore android-security java-security
1个回答
0
投票

我在KeyStore中也遇到稳定性方面的问题。

对我来说,解决方案是用于keyStore.getEntry(KEY_NAME, null)

private key

这是公钥

PrivateKey privKey = ks.getKey(alias, password)

而不是PublicKey pubKey = ks.getCertificate(alias).getPublicKey();

getEntry
© www.soinside.com 2019 - 2024. All rights reserved.