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

Пример кода также доступен по этой ссылке.

Другие вопросы по тегам