Получить закрытый и открытый ключ сертификата X.509 ECDH на Android (Java / Kotlin) - PullRequest
1 голос
/ 25 сентября 2019

В настоящее время я пытаюсь реализовать алгоритм ECDH в моем приложении для Android.Но я столкнулся с проблемой, я хотел бы сохранить закрытый и открытый ключ в Android KeyStore.Однако для этого мне нужно получить сертификат для моей keyPair.И вот где я застрял.

Я не могу получить правильный сертификат, который будет разрешен Android KeyStore для использования.

Вот как я генерирую ключ (урезанная версия)

    val ecParamSpec = ECGenParameterSpec("secp521r1")
    val keyPairGenerator = KeyPairGenerator.getInstance("ECDH", "SC")
    keyPairGenerator.initialize(ecParamSpec, SecureRandom())

    val keyPair = keyPairGenerator.generateKeyPair()

    val privateKey = keyPair.private
    val publicKey = keyPair.public

И для сертификата я попробовал это (использовал SHA256WithECDSA)

    val startDate = Calendar.getInstance()
    val endDate = Calendar.getInstance().apply {
        add(Calendar.YEAR, 20)
    }
    val certBuilder = X509v3CertificateBuilder(
        X500Name("CN=MASTERKEY CA Certificate"),
        BigInteger.valueOf(System.currentTimeMillis()),
        startDate.time,
        endDate.time,
        X500Name("DN=MASTERKEY CA Certificate"),
        SubjectPublicKeyInfo.getInstance(keyPair.public.encoded)
    )
    val builder = JcaContentSignerBuilder("SHA256WithECDSA")
    val signer = builder.build(keyPair.private)
    val certBytes = certBuilder.build(signer).encoded
    val certificateFactory = CertificateFactory.getInstance("X.509")

    val certificate = certificateFactory.generateCertificate(ByteArrayInputStream(certBytes)) as X509Certificate

И это легко понять, что это не сработает, так как алгоритм JcaContentSignerBuilder не совпадает с алгоритмомKeyPairGenerator.И вот тут Android KeyStore начинает говорить, что что-то не так.

java.lang.IllegalArgumentException: private key algorithm does not match algorithm of public key in end entity certificate (at index 0)

Я использовал этот код, чтобы попытаться сохранить ключ в Android KeyStore

keyStore.setEntry("MASTERKEY", KeyStore.PrivateKeyEntry(key[DH.PRIVATE_KEY] as PrivateKey, arrayOf(key[DH.CERTIFICATE] as Certificate)),
                        KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT or KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_SIGN).setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
                            .build())

Я использую spongycastle на случай, если ты спросишь.

Если кто-нибудь сможет мне помочь, я буду очень благодарен!Спасибо всем.

...