Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Store SecretKey in KeyStore

I use a SecretKey to encrypt sensitive data in my application. Currently I am storing my SecretKey in Base64 encoded format in DB or SharedPrefs which is not a safe place to store Secret on a rooted phone. Hence, I want to move my SecretKey to Android KeyStore. The problem I am facing is when I try this sample code from Google, it expects a PrivateKey instead of SecretKey. I couldn't figure out a way to store my SecretKey in KeyStore and fetch it for later use. I tried this:

private static void writeSecretKeyToKeystore(SecretKey secretKey, Context context) {
KeyStore keyStore = null;
try {
  keyStore = KeyStore.getInstance("AndroidKeyStore");
  keyStore.load(null);
  KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
  keyStore.setKeyEntry("Key", secretKeyEntry.getSecretKey().getEncoded(), null);
} catch (KeyStoreException e) {
  e.printStackTrace();
} catch (CertificateException e) {
  e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}

When I try above code, it throws an exception Operation not supported because encoding is unknown.

Any sample code would be of great help.

like image 254
Rajkiran Avatar asked Apr 19 '16 06:04

Rajkiran


People also ask

What can be stored in Android keystore?

The Android Keystore system lets you store cryptographic keys in a container to make them more difficult to extract from the device. Once keys are in the keystore, you can use them for cryptographic operations, with the key material remaining non-exportable.

Where are Android encryption keys stored?

The Android Key Store system lets you store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the key store, they can be used for cryptographic operations with the key material remaining non-exportable.

Where do I put API key Android?

Go to the Google Maps Platform > Credentials page. On the Credentials page, click Create credentials > API key. The API key created dialog displays your newly created API key. Click Close.


1 Answers

WRONG
java.security.KeyStore can store both symmetric and asymmetric keys. You just need to instantiate KeyStore.SecretKeyEntry passing it your SecretKey in the constructor and then use the KeyStore#setEntry method to save it:

keyStore.setEntry(
     "key1",
     new KeyStore.SecretKeyEntry(secretKey),
     new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
             .setBlockMode(KeyProperties.BLOCK_MODE_GCM)
             .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
             .build());

To get it back out use:

SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);

UPDATE
After some research I was surprised to find out, that AndroidKeyStore doesn't support symmetric keys. (see the discussion: https://groups.google.com/forum/#!topic/android-developers/gbmIRKRbfq8)

like image 168
dev.bmax Avatar answered Sep 19 '22 20:09

dev.bmax