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;
}
Другие вопросы по тегам