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

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

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

Caused by: 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)

Мы думаем, что это связано с тем, что шаблон разблокировки телефона не разблокирует хранилище ключей, и/или администратор устройства блокирует хранилище ключей.

Вот как создается хранилище ключей и как сгенерированы ключи:

public SecretKeyWrapper(Context context, String alias) throws GeneralSecurityException, IOException {
    mCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    final KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);

    if (!keyStore.containsAlias(alias)) {
        generateKeyPair(context, alias);
    }

    final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(alias, null);
    mPair = new KeyPair(entry.getCertificate().getPublicKey(), entry.getPrivateKey());
}

private static void generateKeyPair(Context context, String alias) throws GeneralSecurityException {
    final Calendar start = new GregorianCalendar();
    final Calendar end = new GregorianCalendar();
    end.add(Calendar.YEAR, 100);

    final KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
            .setAlias(alias)
            .setSubject(new X500Principal("CN=" + alias))
            .setSerialNumber(BigInteger.ONE)
            .setStartDate(start.getTime())
            .setEndDate(end.getTime())
            .build();

    final KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
    gen.initialize(spec);
    gen.generateKeyPair();
}

Кто-нибудь знает, как:

  • Заблокировать хранилище ключей в качестве администратора устройства?
  • Разблокировать хранилище ключей, когда оно заблокировано администратором устройства?
  • Или воспроизвести эту проблему по-другому?
4b9b3361

Ответ 1

Caused by: java.lang.IllegalStateException: could not generate key in keystore

надеюсь, что первое исключение будет разрешено следующим кодом ниже:

KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);

ks.getEntry(alias, new KeyStore.PasswordProtection(password))

Разблокируйте хранилище ключей, когда оно заблокировано администратором устройства:

KeyStore может быть заблокирован не только на устройствах до ICS. Самый простой способ заблокировать KeyStore:

  • Инициализируйте KeyStore, установив KeyGuard (шаблон, контакт или пароль на блокировку экрана).
  • Добавить ключи или все, что вы храните в KeyStore
  • Перейдите в "Настройки" > "Безопасность" и "Заблокируйте блокировку экрана" на "небезопасный", например, "Слайд".
  • Перезагрузите устройство.

После загрузки устройства KeyStore будет заблокирован. com.android.credentials.UNLOCK намерение начнет действие com.android.settings.CredentialStorage, которое, в свою очередь, покажет UnlockDialog с запросом пароля.

 * KeyStore: LOCKED
 * KeyGuard: OFF/ON
 * Action:   old unlock dialog
 * Notes:    assume old password, need to use it to unlock.
 *           if unlock, ensure key guard before install.
 *           if reset, treat as UNINITALIZED/OFF

Вы можете просто сгенерировать мастер-ключ и сохранить его как частный файл, другие приложения не смогут его прочитать, так что вы будете в порядке на ненагруженных устройствах. Это подход, рекомендованный в блоге разработчиков Android: http://android-developers.blogspot.jp/2013/02/using-cryptography-to-store-credentials.html