Search code examples
androidandroid-keystore

Generate symmetric key and store in android keystore


I am attempting to do the following,

  • Generate a secret key for sqlcipher.
  • Store the secret in android keystore.
  • Retrieve secret from keystore.

I've found nearly everything I need, but I'm having trouble getting the below pieces of code working together.

Pre: Setup keystore

private void InitialiseKeystore() throws ... {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);
    boolean containsAlias = keyStore.containsAlias("com.example.myapp");

    KeyPairGenerator kpg = KeyPairGenerator.getInstance(
            KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");

    if (!containsAlias) {
        kpg.initialize(new KeyGenParameterSpec.Builder(
                alias,
                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                .setDigests(KeyProperties.DIGEST_SHA256,
                        KeyProperties.DIGEST_SHA512)
                .build());

        KeyPair kp = kpg.generateKeyPair();
    }

Generating symmetric key

I found these good examples but they're creating public/private keys, as the same with many others, so a bit confused there, but I have the following.

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); //<------------------------------------- [ERRORS HERE]
SecretKey secretKey = keyGen.generateKey();

Storing in keystore

Reviewing the documentation, it seems I should use KeyStore.SecretKeyEntry to store secrets, so this is what I currently have,

KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
keyStore.setKeyEntry("key1", secretKeyEntry.getSecretKey().getEncoded(), null);

Retrieving from keystore

private static byte[] getRawSecret() throws Exception {
    KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);

    byte[] raw = keyStore.getKey("key1", null).getEncoded();
    return raw;
}

Here's where it goes wrong, in another function I'm trying to call getRawSecret().

SQLiteDatabase.openOrCreateDatabase(databaseFile, getRawSecret().toString(), null);

ERROR: Cannot initialize without a android.security.keystore.KeyGenParameterSpec parameter

So question, how do I create a symmetric key and store in keystore? As the error is telling me to use KeyGenParameterSpec but as in the examples linked above, this wants to create public/private keys. What am I doing wrong?


Solution

  • I used this to solve my issue,

    Guide: https://medium.com/@josiassena/using-the-android-keystore-system-to-store-sensitive-information-3a56175a454b

    Code: https://gist.github.com/JosiasSena/3bf4ca59777f7dedcaf41a495d96d984