John White John White - 1 year ago 142
Java Question

Android KeyStore System - Saving a KeyPair?

I am currently attempting to put together a functioning KeyStore implementation in my Android application. I am currently building against a minimum API of 18 so that I can fully take advantage of a private

for my app. I am attempting to generate
number of
objects, and save them in the
for later retrieval. I have looked at this question, however it seems a bit outdated (2012) and does not really answer anything all that well. Honestly, most of the questions I've found on Stack Overflow seem to be incredibly outdated, like here and here.

So my intended flow is this:

  1. Attempt to retrieve a public key from the certificate correllating with the appropriate alias.

  2. In the event that this public key is null, create a new key.

  3. Utilize
    KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");

  4. Generate the key pair.

Everything up to this point is very straight forward and works just fine. Next is where it gets hairy.

  1. Save the key pair. Initialize the KeyStore via

  2. Attempt to generate an
    through an
    . This certificate is self signed. For the cert, I set the signature algorithm as

  3. Finally, call

For this last step there seem to be two options:

keyStore.setKeyEntry(String alias, byte[] key, Certificate[] chain);


keyStore.setKeyEntry(String alias, Key key, char[] password, Certificate[] chain);

I started with the second of the two, but received entries cannot be protected with passwords
.... Okay, that's odd, why would there be a method that guarantees to throw an exception? Let's try door number 1.

At which point, when I call setKeyEntry, and pass keyPair.getPrivate().getEncoded() as the second argument, I receive Operation not supported because key encoding is unknown
from the system.

So I'm kind of at a loss. Encryption like this is relatively new to me, so I was hoping that someone could shed some light on the very confusing situation that is the Android KeyStore system.

Answer Source

So I have found the answer - hopefully this will help save some issues for future users, as it is not clearly laid out in the docs.

The KeyPairGeneratorSpec.Builder has a method setAlias. When a key is generated, it is automatically stored in the KeyStore under this alias. there is no extra saving that needs to happen to make it work. You can then easily retrieve these keys through instantiating the KeyStore with the same String provider as you did the KeyPairGenerator.