- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有以下几行从 Android 上的 keystore 中获取私钥
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
// generating key pair code omitted
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) this.keyStore.getEntry("alias", null);
一切正常,除了当操作系统从 Android 5.1.1 升级到 Android 6.0.1 时,第 3 行将抛出 java.security.UnrecoverableKeyException: Failed to get information about private key
非常第一次执行。但之后它会再次正常工作。现在我的解决方法是执行该行 2 次。同时,我也想知道是否有更好的方法来避免异常。
异常跟踪
W/System.err﹕ java.security.UnrecoverableKeyException: Failed to obtain information about private key
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:217)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:253)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(AndroidKeyStoreProvider.java:263)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:93)
W/System.err﹕ at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:372)
W/System.err﹕ at java.security.KeyStore.getEntry(KeyStore.java:645)
W/System.err﹕ at com.example.keystoretest.MainActivity.onCreate(MainActivity.java:113)
W/System.err﹕ at android.app.Activity.performCreate(Activity.java:6251)
W/System.err﹕ at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
W/System.err﹕ at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
W/System.err﹕ at android.app.ActivityThread.-wrap11(ActivityThread.java)
W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
W/System.err﹕ at android.os.Looper.loop(Looper.java:148)
W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5417)
W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
W/System.err﹕ Caused by: android.security.KeyStoreException: Invalid key blob
W/System.err﹕ at android.security.KeyStore.getKeyStoreException(KeyStore.java:632)
W/System.err﹕ at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:218)
W/System.err﹕ ... 18 more
最佳答案
Ans:在加载 Android key 并从 Keystore 存储公钥时,如果状态被锁定或未初始化,则可能会发生此错误。
@NonNull
public static AndroidKeyStorePublicKey loadAndroidKeyStorePublicKeyFromKeystore(
@NonNull KeyStore keyStore, @NonNull String privateKeyAlias)
throws UnrecoverableKeyException {
KeyCharacteristics keyCharacteristics = new KeyCharacteristics();
int errorCode = keyStore.getKeyCharacteristics(privateKeyAlias, null,
null, keyCharacteristics);
if (errorCode != KeyStore.NO_ERROR) {
throw (UnrecoverableKeyException) new UnrecoverableKeyException(
"Failed to obtain information about private key")
.initCause(KeyStore.getKeyStoreException(errorCode)); // this exception is generated
}
......
......
......
}
KeyStore 有 10 个响应码。他们是
// ResponseCodes
NO_ERROR = 1;
LOCKED = 2;
UNINITIALIZED = 3;
SYSTEM_ERROR = 4;
PROTOCOL_ERROR = 5;
PERMISSION_DENIED = 6;
KEY_NOT_FOUND = 7;
VALUE_CORRUPTED = 8;
UNDEFINED_ACTION = 9;
WRONG_PASSWORD = 10;
KeyStore has 3 states. They are UNLOCKED, LOCKED, UNINITIALIZED
NO_ERROR is only happened when the state is UNLOCKED. For your upgrading case the state is LOCKED or UNINITIALIZED for first time, so the error is happened only once.
public State state() {
execute('t');
switch (mError) {
case NO_ERROR:
return State.UNLOCKED;
case LOCKED:
return State.LOCKED;
case UNINITIALIZED:
return State.UNINITIALIZED;
default:
throw new AssertionError(mError);
}
}
资源链接:
从您的错误日志中,现在很明显
W/System.err﹕ Caused by: android.security.KeyStoreException: Invalid key blob
这是用户尝试从 LOCK/UNINITIALIZED 解锁时引起的主要问题。默认情况下定义为 30 秒计时。 这个问题是API相关的实现问题。
/**
* If the user has unlocked the device Within the last this number of seconds,
* it can be considered as an authenticator.
*/
private static final int AUTHENTICATION_DURATION_SECONDS = 30;
对于加密/解密,使用生成的 key 的某些数据仅在用户刚刚通过设备凭据进行身份验证时才有效。错误发生在
// Try encrypting something, it will only work if the user authenticated within
// the last AUTHENTICATION_DURATION_SECONDS seconds.
cipher.init(Cipher.ENCRYPT_MODE, secretKey); // error is generated from here.
从这里抛出实际错误。您的错误是由 InvalidKeyException
生成的。
您必须从 catch 参数中删除 InvalidKeyException
类。这仍然允许您检查 InvalidKeyException
。检查后,您必须第二次尝试使用代码,以便问题不会显示在眼睛中,但进行 2 次检查可能会解决您的问题。我没有测试过代码,但应该如下所示:
try {
....
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) this.keyStore.getEntry("alias", null);
....
} catch (final Exception e) {
e.printStackTrace();
if (e instanceof InvalidKeyException) { // bypass InvalidKeyException
.......
// You can again call the method and make a counter for deadlock situation or implement your own code according to your situation
if (retry) {
keyStore.deleteEntry(keyName);
return getCypher(keyName, false);
} else {
throw e;
}
}
}
关于java.security.UnrecoverableKeyException : Failed to obtain information about private key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36652675/
我有一个访问 keystore 的代码。当我的密码错误时,我得到一个类型为 UnrecoverableKeyException 的异常.所以我把我的代码写成: try {
我正在使用新的 EncryptedSharedPreferences以谷歌推荐的方式上课: private fun securePrefs(context: Context): SharedPrefe
问题:需要将RSA私钥保存在加密的地方。尝试为此目的使用 KeyStore。 代码 fragment : package com.example.encryptiontest; import java
我在服务器上运行 Apache Tomcat/7.0.68,我正在尝试为其自动更新证书。 证书和私钥是通过 Java 的 keytool 从 PKCS#12 文件(Powershell 脚本摘录)导入
请注意:虽然这个具体问题涉及Ldaptive库,我坚信它本质上纯粹是一个 Java keytool/SSL/Spring 问题。 我在我的 Java (Spring) 应用程序服务器上使用 Ldapt
在我们的应用中,我们遇到了 Android keystore 中的数据突然变得无法访问的问题。我们看到的具体异常如下: java.security.UnrecoverableKeyException:
我正在尝试用签名证书替换自签名码头证书。我替换了 2 个文件 jetty.crt 和 jetty.key.Run 2 个命令: openssl pkcs12 -inkey jetty.key -in
我已经更改了我的 keystore 的密码,其中有一堆 key ,使用以下命令: keytool -storepasswd -storetype jceks -keystore my.keystore
我有以下代码尝试使用 SHA-256 哈希作为密码来初始化 KeyManagerFactory。 public static KeyManager[] getKeystoreManagers()
我有以下几行从 Android 上的 keystore 中获取私钥 KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); keySt
我得到了一个名为 ABCC_client.store 的 jks keystore 。当我将此 keystore 导入 cacerts 并尝试连接时,它说没有这样的算法错误。 PFA 堆栈跟踪
我无法使用现有的 keystore 签署我的 apk。它在签名时给我这个错误:com.android.ide.common.signing.KeytoolException: 读取 key 失败无法恢
我正尝试在 Tomcat 中为我的 REST Api 配置对 SSL(HTTPS) 的支持。我在我的 Mac OS X Yosemite 上使用 Eclipse Mars。我编辑了 Tomcat 的
大家好,我使用 AES 进行加密,我所做的是在文本文件中加密数据并存储给定位置,如果在同一个类文件中给出,解密工作正常,我创建了一个不同的 java类来解密文件,我使用带有用户名和密码的 Javake
当我调用 java.security.KeyStore 下的函数时: public final Key getKey(String alias, char[] password) 我收到以下错误: j
我正在尝试从从 Google 服务帐户控制台下载的 .p12 文件中提取私钥。 我正在从文件夹位置读取此 .p12 并创建 KeyStore 对象。 KeyStore myStore = null;
我是一名优秀的程序员,十分优秀!