Android KeyStore - How to save an RSA PrivateKey

FUGAZI picture FUGAZI · Nov 21, 2013 · Viewed 12.9k times · Source

I receive from a web service(made by myself) an RSA PrivateKey PKCS#8 encoded in a base 64 String. My Android app must save this key somewhere into the phone securely.

From the 4.3 version of Android, it's possible saving keys using the new KeyStore API. I've found an article with code axample that shows how to generate a KeyPair with the Specification needed to store the keys. And after to recover the keys.

// generate a key pair
Context ctx = getContext();
Calendar notBefore = Calendar.getInstance()
Calendar notAfter = Calendar.getInstance();
notAfter.add(1, Calendar.YEAR);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(ctx)
            .setAlias("key1")
            .setSubject(
                    new X500Principal(String.format("CN=%s, OU=%s", alais,
                            ctx.getPackageName())))
            .setSerialNumber(BigInteger.ONE).setStartDate(notBefore.getTime())
            .setEndDate(notAfter.getTime()).build();

KeyPairGenerator kpGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
kpGenerator.initialize(spec);
KeyPair kp = kpGenerator.generateKeyPair();

// in another part of the app, access the keys
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry("key1", null);
RSAPublicKey pubKey = (RSAPublicKey)keyEntry.getCertificate().getPublicKey();
RSAPrivateKey privKey = (RSAPrivateKey) keyEntry.getPrivateKey();

But i don't understand how can i save an existing key to it. Can anybody help me? Thanks in advance

Answer

Jcs picture Jcs · Nov 23, 2013

In KeyStore the private keys must be stored along with a certificate (even a fake self-signed certificate). To store your key in the AndroidKeyStore you should follow these steps:

  1. decode the Base64 PKCS#8 to get a PrivateKey instance
  2. either the web service sends a certificate (or certificate chain) along with the private key or the PKCS#8 blob also contain the public key.
  3. if required you need to generate a certificate for the private key. The BouncyCastle library can do this (a code sample can be found here).

Now you can add your key to the keystore.

PrivateKey myKey = getKey();
X509Certificate certificate = getCertificate();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
keystore.setKeyEntry("anAlias", myKey, null, new Certificate[] { certificate });