2015-06-09 4 views
21

В настоящее время мы столкнулись с проблемой, где иногда, когда пользователь installes наше приложение, приложение пытается получить доступ и генерировать ключ в хранилище, но хранилище ключей выдает это исключение:Не удается создать ключ в 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(); 
} 

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

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

Показать код, как вы создаете Keystore. – Jorgesys

+1

Вы нашли решение? –

ответ

10

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 заблокирован является:

  1. Initialize KeyStore установкой KeyGuard (шаблон, контактный или пароль на блокировки экрана)
  2. Добавить ключи или что вы храните в KeyStore
  3. Перейти в раздел Настройки > Безопасность и изменение Блокировка экрана для чего-то «небезопасного», например, Слайд.
  4. Перезагрузите устройство.

После того, как устройство загрузилось, 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

+0

Спасибо за ваш ответ Джамиль. Однако я не вижу, как вызов метода KeyStore.getEntry (...) 'с паролем имеет смысл, учитывая, что запись KeyStore не была создана с помощью пароля (см. Вызов метода KeyPairGenerator. GenerateKeyPair()' в вопрос). Пожалуйста, объясни. –