Generate elliptic curve KeyPair via KeyStore on API Level <23

让人想犯罪 __ 提交于 2019-12-23 05:15:48

问题


I need to generate an elliptic key pair in Android and store it to KeyStore to protect a private key from extraction.

I was able to generate a key pair using Spongycastle library, but I cannot import the key pair in the KeyStore. Firstly, because I do not have a certificate and secondly, even if I tried to create one, it did not import the key either.

I though of generating a key pair using KeyGenParameterSpec, but it's not accessible in APIs below version 23.

To sum up my question, is there a non-hacky way how to do it with general Android resources that are meant for that? Or it is simply impossible to work with elliptic curve keys on version Lollipop and lower?


回答1:


In the documentation of the Android keystore system is a section on supported key generation algorithms. It states:

Prior to API Level 23, EC keys can be generated using KeyPairGenerator of algorithm "RSA" initialized KeyPairGeneratorSpec whose key type is set to "EC" using setKeyType(String). EC curve name cannot be specified using this method -- a NIST P-curve is automatically chosen based on the requested key size.

If you can live with these limitations then you can use the Android Keystore for API levels down to API 19. It might seem that you can do down to API 18, but the necessary methods to set the key size and key type do not exist until API level 19. The name of the class used to build the parameter spec for API levels 19 through 22 inclusive is KeyPairGeneratorSpec.Builder. This is very similar to the name of the class used for API level 23 and above, KeyGenParameterSpec.Builder, so be careful not to confuse the two.

Here is a little snippet of code illustrating the above. It should run on 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();
}



回答2:


Generate a secp256r1 key pair code:

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


来源:https://stackoverflow.com/questions/50130448/generate-elliptic-curve-keypair-via-keystore-on-api-level-23

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!