ECDH с использованием Android KeyStore сгенерированный закрытый ключ
Я пытаюсь реализовать ECDH в Android, используя частный сгенерированный Android KeyStore Provider.
public byte[] ecdh(PublicKey otherPubKey) throws Exception {
try {
ECPublicKey ecPubKey = (ECPublicKey) otherPubKey;
KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
PrivateKey pk = (PrivateKey) LoadPrivateKey("Backend");
keyAgreement.init(pk);
keyAgreement.doPhase(ecPubKey, true);
return (keyAgreement.generateSecret());
}
catch (Exception e)
{
Log.e("failure", e.toString());
return null;
}
}
Однако это исключение отлавливается в keyAgreement.init (pk):
E / fail: java.security.InvalidKeyException: не может идентифицировать закрытый ключ EC: java.security.InvalidKeyException: нет кодировки для закрытого ключа EC
Я успешно сгенерировал пару открытых / закрытых ключей "Backend", используя:
public void GenerateNewKeyPair(String alias)
throws Exception {
if (!keyStore.containsAlias(alias)) {
// use the Android keystore
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, ANDROID_KEYSTORE);
keyGen.initialize(
new KeyGenParameterSpec.Builder(
alias,
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
.setDigests(KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA384,
KeyProperties.DIGEST_SHA512)
.setRandomizedEncryptionRequired(true)
.build());
// generates the keypair
KeyPair keyPair = keyGen.generateKeyPair();
}
}
И я загружаю закрытый ключ, используя:
public PrivateKey LoadPrivateKey(String alias) throws Exception {
PrivateKey key = (PrivateKey) keyStore.getKey(alias, null);
return key;
}
Кто-нибудь имеет представление о том, что происходит, и может помочь мне понять, как это исправить? Спасибо!
2 ответа
Насколько я знаю из исследований и проб и ошибок, в настоящее время это не поддерживается.
Я считаю, что лучшее, что вы можете сделать, - это подписать открытый ключ пары ключей EC, сгенерированной вами вне AndroidKeyStore, парой ключей EC, которая хранится в AndroidKeyStore. Затем вы можете отправить этот подписанный открытый ключ другой стороне с сертификатом подписывающего ключа, сгенерировать общий секрет (вне AndroidKeyStore), а затем сохранить SecretKey, полученный с использованием KDF, в сгенерированном секрете. Я рекомендую использовать эту пару ключей, не сгенерированную в AndroidKeyStore, один раз (поэтому только для целей получения секрета) и повторять этот процесс для повторного ввода ключа, когда это будет сочтено необходимым.
РЕДАКТИРОВАТЬ: Когда я сказал "сохранить SecretKey", я имел в виду AndroidKeyStore. Этот ключ первоначально будет находиться в том, что называется "нормальным миром" в этом контексте, но это лучшее, что вы можете сделать на данный момент.
ECDH поддерживается на уровне API 23. Пожалуйста, обратитесь к документации Android по системе Android Keystore
Пример кода также доступен по этой ссылке.