android.security.KeyStoreException: недействительный ключевой объект
Я не могу получить (закрытый) ключ из KeyStore на Android. Проблема возникает в основном на устройствах Samsung (S6, S6 Edge) и Android 6.
android.security.KeyStoreException: недействительный ключевой объект
выбрасывается при вызове следующей строки (где alias - имя для ключа хранилища).
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
Сам KeyStore получается
KeyStore.getInstance("AndroidKeyStore");
И ключ генерируется следующим методом:
private static void createKey(String alias, String subject, KeyStore keyStore, BigInteger serialNumber, Date startDate, Date endDate, String algorithm, String keyStoreProvider, Context context)
throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
if (keyStore.containsAlias(alias)) {
// Key already exists.
return;
}
// Generate keys.
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
.setAlias(alias)
.setSubject(new X500Principal(subject))
.setSerialNumber(serialNumber)
.setStartDate(startDate)
.setEndDate(endDate)
.build();
KeyPairGenerator generator = KeyPairGenerator.getInstance(algorithm, keyStoreProvider);
generator.initialize(spec);
KeyPair keyPair = generator.generateKeyPair();
}
Где алгоритм "RSA", а keyStoreProvider - "AndroidKeyStore".
Часть трассировки стека:
android.security.KeyStoreException: Invalid key blob
at android.security.KeyStore.getKeyStoreException(KeyStore.java:939)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:216)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:252)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(AndroidKeyStoreProvider.java:263)
at android.security.keystore.AndroidKeyStoreSpi.engineGetKey(AndroidKeyStoreSpi.java:93)
at java.security.KeyStoreSpi.engineGetEntry(KeyStoreSpi.java:372)
at java.security.KeyStore.getEntry(KeyStore.java:645)
Исключение вызывает java.security.UnrecoverableKeyException: не удалось получить информацию о секретном ключе, который должен быть выдан.
Мне не удалось найти более подробную информацию о "недействительном ключевом блобе", только то, что само сообщение определено здесь: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/security/keymaster/KeymasterDefs.java
1 ответ
Эта проблема возникает, когда пользователь пытается UNLOCK
от LOCK/UNINITIALIZED
, По умолчанию определяется как 30 secs
для сроков. Эта проблема связана с реализацией API.
Эта ошибка генерируется из InvalidKeyException
, Обойдя это исключение и снова вызвав метод, вы можете избавиться от этой ошибки.
Вы должны удалить InvalidKeyException
класс из аргумента catch. Это все еще позволит вам проверить InvalidKeyException
, После проверки вы должны повторить попытку с кодом, чтобы проблема не отображалась на глаз, но повторная проверка может решить вашу проблему. Код приведен ниже.
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) this.keyStore
.getEntry("alias", null);
} catch (InvalidKeyException ex) {
ex.printStackTrace();
if (ex 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 ex;
}
}
} catch (final Exception e) {
e.printStackTrace();
throw e;
}
Вы можете увидеть мой другой ответ, который описывает одну за другой возникающую проблему и решение.
ОБНОВЛЕНИЕ от Ankis:
Как вы решили проблему, изменив InvalidKeyException
в UnrecoverableKeyException
, Поэтому я обновил в соответствии с вашим предложением, чтобы мир мог знать фактический ответ. Спасибо, что поделился:).
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) this.keyStore
.getEntry("alias", null);
} catch (UnrecoverableKeyException ex) {
ex.printStackTrace();
// 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);
}
} catch (final Exception e) {
e.printStackTrace();
throw e;
}