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();
}