Android Keystore Error "не удалось создать ключ в хранилище ключей"

Я получаю сообщение об ошибке, пытающееся создать ключ для определенных устройств. Я могу воспроизвести ошибку на Samsung Galaxy Note, работающей 4.4.2.

java.lang.IllegalStateException: could not generate key in keystore at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:100) at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275) at com.eric.demo.MainActivity.generateKeyPair(MainActivity.java:65) at com.eric.demo.MainActivity.onClickButton(MainActivity.java:43) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at android.view.View$1.onClick(View.java:3964) at android.view.View.performClick(View.java:4640) at android.view.View$PerformClick.run(View.java:19421) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5476) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method) 

Я создал небольшое приложение, чтобы генерировать ключ, копируя код по строкам со страницы разработчика Android https://developer.android.com/training/articles/keystore.html в разделе «Создание нового закрытого ключа».

  public void onClickButton (View view) { try { generateKeyPair(this, "test3"); } catch (Exception e){ Log.wtf("exception", e); } } private void generateKeyPair(Context context, String alias) throws Exception { Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); cal.add(Calendar.YEAR, 1); Date end = cal.getTime(); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); kpg.initialize(new KeyPairGeneratorSpec.Builder(getApplicationContext()) .setAlias(alias) .setStartDate(now) .setEndDate(end) .setSerialNumber(BigInteger.valueOf(1)) .setSubject(new X500Principal("CN=test3")) .build()); KeyPair kp = kpg.generateKeyPair(); } 

Ошибка, похоже, происходит в kpg.generateKeyPair (), внутри AndroidKeyPairGenerator.java:

 if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, keyType, mSpec.getKeySize(), mSpec.getFlags(), args)) { throw new IllegalStateException("could not generate key in keystore"); } 

И в KeyStore.java:

 public boolean generate(String key, int uid, int keyType, int keySize, int flags, byte[][] args) { try { return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return false; } } 

Кажется, что вызов mBinder.generate () возвращает 2, что означает, что хранилище ключей заблокировано?

 // ResponseCodes public static final int NO_ERROR = 1; public static final int LOCKED = 2; public static final int UNINITIALIZED = 3; public static final int SYSTEM_ERROR = 4; public static final int PROTOCOL_ERROR = 5; public static final int PERMISSION_DENIED = 6; public static final int KEY_NOT_FOUND = 7; public static final int VALUE_CORRUPTED = 8; public static final int UNDEFINED_ACTION = 9; public static final int WRONG_PASSWORD = 10; 

Ошибка может быть связана с этой проблемой с keystore https://code.google.com/p/android/issues/detail?id=177459&q=could%20not%20generate%20key%20in%20keystore&colspec=ID%20Type% 20Status% 20Owner% 20Summary% 20Stars

Несколько вещей, которые я пробовал индивидуально и сочетал следующее:
1. Требуется настройка шифрования. В результате возникает еще одна ошибка: «Хранилище ключей Android должно быть в инициализированном и разблокированном состоянии, если требуется шифрование»
2. Установка экрана блокировки (шаблон, ПИН-код, НЕТ, пароль, проведите по экрану). Такое же поведение
3. Программно пытаться разблокировать или перезагрузить хранилище учетных данных с помощью startActivity(new Intent("com.android.credentials.UNLOCK")); Или startActivity(new Intent("com.android.credentials.RESET")); Попытка разблокировки показывает сообщение «ввести пароль для хранения учетных данных», в котором нет разумного пароля, и даже очистка учетных данных не помогает.

Хотя я не знаю полного ответа, я могу продолжить поиск. Взаимодействие связующего с другой стороны mBinder является родным хранилищем ключей . Если я полностью помню, это поведение: либо 1) поддерживать ключевые операции на уровне программного обеспечения, либо 2) делегировать предоставленную OEM-библиотеку-клавиатуру, которая (предположительно) может быть подключена к хранилищу ключей OEM-оборудования. Подробнее об этом здесь , здесь и здесь .

Примечание. Я откажусь от обычной политики SO по привлечению внешнего контента ссылки в ответ, так как я связываю вас с тремя статьями, которые составляют все> 1 страницу, и кажется, что смешно публиковать 6-страничный ответ; )

Если ваш код в порядке, помните, что вам нужно настроить PIN / PW / Fingerprint (Безопасная разблокировка) для вашего устройства, чтобы хранилище ключей начало работать. Простой салфетка даст такую ​​ошибку, если вы попытаетесь сгенерировать ключевые пары.

Я думаю, что это правильное направление: щелкните правой кнопкой мыши по проекту> Android-инструменты> Экспорт подписанного пакета приложений. Появится мастер экспорта приложений для Android. Выберите проект, который я хочу экспортировать, нажмите «Далее». Появится экран выбора Keystore.

Intereting Posts