2015-11-28 3 views
3

Я использую приведенный ниже код, чтобы создать ключ hmac и вернуть его в виде строки.Хранение ключа hmac в хранилище ключей Android

KeyGenerator keyGen = null; 
    try { 
     keyGen = KeyGenerator.getInstance("HmacSHA256"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    SecretKey key = keyGen.generateKey(); 
    byte[] encoded = key.getEncoded(); 
    String s=Base64.encodeToString(encoded, Base64.DEFAULT); 
    Log.i("Hmac key before encrypt",s); 

    try { 
     KeyStore keystore = KeyStore.getInstance("AndroidKeyStore"); 
     keystore.load(null, null); 
     KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry("temp", null); 
     RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey(); 

     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
     byte[] cipherBytes = cipher.doFinal(encoded); 

     return Base64.encodeToString(cipherBytes,Base64.DEFAULT); 


    } catch (UnrecoverableEntryException e) { 
     e.printStackTrace(); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (KeyStoreException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (CertificateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

Как сохранить это в хранилище андроидов ?. Я попытался с помощью код ниже:

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
     keyStore.load(null); 

     KeyStore.ProtectionParameter param = new KeyStore.PasswordProtection("test".toCharArray()); 
     keyStore.setEntry("key1",hmacKey,param); 

Я не получить ошибки, независимо от того, какой формат hmacKey в: String/Bytes или javax.crypto.SecretKey. Ниже приведены ошибки: В случае прохождения ключа hmacKey:

Wrong 2nd argument type. Found: 'java.security.Key', required: 'java.security.KeyStore.Entry' 

же в тех случаях, когда я передать строку или массив байтов.

Если я задаю параметр java.security.KeyStore.Entry, он все равно не работает.

Правильно ли это? Может ли кто-нибудь указать, как ключ HMAC можно сохранить в хранилище ключей, используя псевдоним. Как преобразовать ключ hmack в формат java.security.KeyStore.Entry?

+0

Извините за неоднозначной. Отредактировал вопрос – Sid

+0

Не можете ли вы просто сохранить «ключ», как сгенерировано выше? Я вижу много пуха в вопросе. Это не похоже на MCSE. –

+0

Нет, он не может быть сохранен как таковой. В настоящее время я использую общие настройки для хранения этого ключа. Не уверен, есть ли там аспект безопасности, поэтому я хотел сохранить его в хранилище ключей. Первая часть кода работает абсолютно нормально, и я могу создать ключ hmack, а также вернуть его. Его часть, где я пытаюсь сохранить его в хранилище ключей Android, с псевдонимом, который вызывает проблему. – Sid

ответ

3

Магазин ключей Android был создан, чтобы вы могли использовать асимметричные клавиши и симметричные клавиши вне ваш код приложения. Как указано in the training material:

Ключевой материал никогда не входит в процесс подачи заявки. Когда приложение выполняет криптографические операции с использованием ключа Keystore Android, за кулисами открытый текст, зашифрованный текст и сообщения, которые должны быть подписаны или проверены, передаются в системный процесс, который выполняет криптографические операции. Если процесс приложения взломан, злоумышленник может использовать ключи приложения, но не сможет извлечь свой ключевой материал (например, для использования вне устройства Android).

Таким образом, идея генерации ключа внутри кода приложения - и, следовательно, вне хранилища ключей - не является хорошей идеей. Как создать секретный ключ внутри хранилища ключей определяется для ключей HMAC в API for the KeyGenParameterSpec class:

KeyGenerator keyGenerator = KeyGenerator.getInstance(
     KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore"); 
keyGenerator.initialize(
     new KeyGenParameterSpec.Builder("key2", KeyProperties.PURPOSE_SIGN).build()); 
SecretKey key = keyGenerator.generateKey(); 
Mac mac = Mac.getInstance("HmacSHA256"); 
mac.init(key); 
... 

// The key can also be obtained from the Android Keystore any time as follows: 
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 
key = (SecretKey) keyStore.getKey("key2", null); 

Другие ключевые типы могут быть найдены in the KeyProperties class

+0

Дело в том, что я получаю зашифрованный ключ hmack с сервера, и поэтому мне просто нужно сохранить его в самой безопасной версии, доступной на устройстве. Я потом извлечу его, расшифрую с помощью закрытого ключа и использую его по мере необходимости. Я считал, что хранилище ключей будет безопаснее, чем общие предпочтения, поэтому хотел использовать его для хранения ключа. То, где я застрял, и поэтому я использую общие настройки на данный момент. Любая идея о том, как я могу сохранить созданный извне hmac в хранилище ключей? Также спасибо Маартену за постоянное изучение этого. – Sid

+0

Как насчет обертывания этого ключа ключом, который находится в магазине? –

+0

Не знаете, как это сделать, если вы имеете в виду приведение его к записи в хранилище ключей, это не сработает. Также в любой момент времени у меня будет только открытая/закрытая ключевая пара в моем хранилище ключей.Наряду с этим я хотел сохранить ключ hmac. – Sid