- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我们的应用中,我们遇到了 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
我们无法找到重现该问题的可靠方法。有几篇文章提到了可能导致 keystore “忘记” key 或被锁定的可能状态,例如 here 。然而,据我所知,我们还没有陷入任何这些边缘情况。第一次设置 key 后让设备静置一段时间后似乎会发生这种情况。我们已经在多个模拟器和设备(从 21 到 26 个)上看到了这种情况。此外,这些设备使用滑动解锁或 PIN 码。更改 PIN 码或安全方法似乎不会导致该问题。同样,此问题似乎是在设备闲置几天后发生的。
我发现了另外两个 SO here和 here以及一个 Google issue 。如果我理解正确,两者中链接的答案似乎依赖于调用者在创建 key 时调用 setUserAuthenticationValidityDurationSeconds 的前提,而我们还没有这样做。此外,给定的解决方案似乎仅依赖于删除 key 并生成一个新 key 。
下面是我们针对 >= API 23 版本的 key 设置。我省略了 23 之前版本的 key 生成,因为我们主要在 >= 23 的 API 上看到了这一点。
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();
}
然后,我们稍后尝试通过 keyStore.getEntry(KEY_NAME, null)
访问 key 。同样,这会工作一段时间,但随后将开始抛出上述异常。
最佳答案
我还遇到了 KeyStore 的稳定性问题。
解决方案是使用 private key
PrivateKey privKey = ks.getKey(alias, password)
这就是公钥
PublicKey pubKey = ks.getCertificate(alias).getPublicKey();
而不是 getEntry
ks.getEntry(alias, password)
问题不在于您创建 key 的方式,而在于您读取 key 的方式。
一年多以来再也没有遇到过这个问题。
关于android - UnrecoverableKeyException 获取私钥信息失败,KeyStoreException : Invalid key blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48290355/
我是一名优秀的程序员,十分优秀!