Генерация эллиптической кривой KeyPair через KeyStore на уровне API <23 - PullRequest
0 голосов
/ 02 мая 2018

Мне нужно сгенерировать пару эллиптических ключей в Android и сохранить их в KeyStore, чтобы защитить закрытый ключ от извлечения.

Мне удалось сгенерировать пару ключей с помощью библиотеки Spongycastle, но я не могу импортировать пару ключей в KeyStore. Во-первых, поскольку у меня нет сертификата, а во-вторых, даже если я попытался его создать, он также не импортировал ключ.

Я, хотя и генерировал пару ключей с использованием KeyGenParameterSpec, но он недоступен в API ниже версии 23.

Подводя итог моему вопросу, есть ли нехакерный способ, как это сделать с общими ресурсами Android, предназначенными для этого? Или просто невозможно работать с ключами эллиптической кривой на версии Lollipop и ниже?

Ответы [ 2 ]

0 голосов
/ 18 июля 2019

Создание кода пары ключей secp256r1:

val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore")
val parameterSpec = KeyGenParameterSpec.Builder("container", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
                .setAlgorithmParameterSpec(ECGenParameterSpec("secp256r1"))
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
                .build()
kpg.initialize(parameterSpec)
val keyPair = kpg.generateKeyPair()

val ecPublicKey = keyPair.public as ECPublicKey
val ecPrivateKey = keyPair.private as ECPrivateKey
0 голосов
/ 05 мая 2018

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

До API уровня 23 ключи EC можно создавать с помощью KeyPairGenerator. алгоритма "RSA" инициализировал KeyPairGeneratorSpec, тип ключа которого установите «EC», используя setKeyType (String). Название кривой ЕС не может быть определяется с использованием этого метода - автоматически выбирается P-кривая NIST на основе запрошенного размера ключа.

Если вы можете жить с этими ограничениями, вы можете использовать Android Keystore для уровней API вплоть до API 19. Может показаться, что вы можете использовать API 18, но необходимые методы для установки размера ключа и типа ключа делают не существует до уровня API 19. Имя класса, используемого для построения спецификации параметров для уровней API с 19 по 22 включительно, составляет KeyPairGeneratorSpec.Builder. Это очень похоже на имя класса, используемого для API уровня 23 и выше, KeyGenParameterSpec.Builder, поэтому будьте осторожны, чтобы не перепутать их.

Вот небольшой фрагмент кода, иллюстрирующий вышесказанное. Он должен работать на API 19.

private void createEcKey() throws Exception {
    Calendar start = Calendar.getInstance();
    Calendar end = Calendar.getInstance();
    end.add(Calendar.YEAR, 1);
    KeyPairGeneratorSpec spec =
            new KeyPairGeneratorSpec.Builder(this)
                    .setAlias("myKey")
                    .setKeySize(256)
                    .setKeyType("EC")
                    .setSubject(new X500Principal("CN=Dodgy Stuff"))
                    .setSerialNumber(BigInteger.valueOf(123456789L))
                    .setStartDate(start.getTime())
                    .setEndDate(end.getTime())
                    .build();
    KeyPairGenerator kpg = KeyPairGenerator.getInstance(
            "RSA", "AndroidKeyStore");
    kpg.initialize(spec);
    KeyPair keyPair = kpg.generateKeyPair();
    ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
    ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();

    //
    // The following will throw an Exception if uncommented, because
    //    the private key is not allowed to leave the protection of
    //    the Androud Keystore boundary.
    //
    // byte [] privEncoded = ecPrivateKey.getEncoded();
}
...