Intereting Posts
Создание анимации в ImageView при изменении ресурса изображения Как начать отображение списка из определенной позиции позиции Ошибка EditText: дубликаты контента после нажатия символа ограничения ResultCode всегда равен 0, а запрос всегда равен -1. Activity.onActivityResult (); Как загрузить изображение из URL-адреса в просмотрщик Разрыв цепи RxJava на условном Синхронизировать данные на устройстве с сервером? InAppBilling V3 – «buyData» и «dataSignature» являются нулевыми при покупке элемента подписки Android Создание простого меню программно Как разместить на стене facebook android-sdk: 4.0.0 RequestFactory медленнее на Android Укажите интервалы для диспетчера местоположений для передачи текущего местоположения в Android Разбиение на страницы в Android TextView Каковы коды ответов (значения), возвращаемые сервером Google Play в ответ на лицензию? Почему Android использует несколько контекстов, и каждый отличается?

Java.security.UnrecoverableKeyException: Не удалось получить информацию о закрытом ключе

У меня есть следующие строки, чтобы получить секретный ключ из хранилища ключей на Android

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 obtain 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 

    Когда эта ошибка происходит и почему?

    Ответ: При загрузке ключей Android и сохранении открытого ключа из 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 имеет 3 состояния. Они разблокированы, заблокированы, UNINITIALIZED

    NO_ERROR происходит только тогда, когда состояние UNLOCKED. Для вашего случая обновления состояние ЗАБЛОКИРОВАНО или UNINITIALIZED в первый раз, поэтому ошибка происходит только один раз.

    Код проверки состояния приведен ниже:

     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); } } 

    Ссылка ресурса:

    1. Класс JavaKeyStoreProvider
    2. Класс java класса KeyStore

    ОБНОВИТЬ:

    Из вашего журнала ошибок теперь ясно, что

     W/System.err﹕ Caused by: android.security.KeyStoreException: Invalid key blob 

    Это основная проблема, которая возникает при попытке пользователя UNLOCK от 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; 

    Для шифрования / дешифрования некоторые данные с сгенерированным ключом работают только в том случае, если пользователь только что аутентифицировался через учетные данные устройства. Ошибка возникает из

     // 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 .

    Решение:

    Вы должны удалить класс InvalidKeyException из аргумента catch. Это все равно позволит вам проверить 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; } } } 

    Ссылка ресурса:

    1. MainActivity.java
    2. Android.security.KeyStoreException: неверный ключ blob