2015-06-26 3 views
38

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

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; 

Ошибка может быть несколько связанных с этим вопросом с хранилищем ключами 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. Установка экрана блокировки (шаблон, PIN-код, NONE, пароль, проведите по экрану). То же поведение
3. Программно пытаться разблокировать или перезагрузить хранилище учетных данных с помощью startActivity(new Intent("com.android.credentials.UNLOCK")); или startActivity(new Intent("com.android.credentials.RESET")); Попытка разблокировки показывает сообщение «ввести пароль для хранения учетных данных», в котором не работает разумный пароль, и даже очистка учетных данных не помогает.

+0

Я видел это обходное решение в других местах, но не похоже, что вы пробовали эту точную комбинацию: если блокировка экрана отключена: удалите приложение, установите блокировку экрана, отключите блокировку экрана, затем переустановите. Если заблокирован экран блокировки, удалите, отключите блокировку экрана, установите блокировку экрана, затем переустановите. У меня нет устройства для воспроизведения, но я ищу обходной путь для одного из моих пользователей. –

+0

Когда вас попросят ввести пароль для хранения учетных данных, правильным паролем может быть резервный PIN-код, который вы выбираете при настройке шаблона. По крайней мере, это было моим делом. – JerabekJakub

ответ

-4

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

2

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

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

0

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