Подтвердить что ты не робот

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;

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

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