How to store key using Android Key Store Provider
Solution 1
Why is it blueBirdKeyStore in:
blueBirdKeyStorage.loadKeyStore();
Shouldn't it be:
keyStorage.loadKeyStore();
Also, you haven't used the 'alias' in your loadPrivateKey():
KeyStore.Entry entry = keyStore.getEntry(EnhancedCredentialStore.KEY_ALIAS, null);
Now, I'm not sure, but shouldn't you be using the 'alias' in this?
Solution 2
Your method to check if your key exists is flawed:
if (keyStore.isKeyEntry(alias)) {
Log.e("E", "Could not find key alias: " + alias);
return null;
}
According to the javadoc .isKeyEntry()
has the following behavior
Returns true if the entry identified by the given alias was created by a call to setKeyEntry, or created by a call to setEntry with a PrivateKeyEntry or a SecretKeyEntry.
but your key was not created through setEntry()
. I guess if you just load the key with
KeyStore.Entry entry = ks.getEntry(alias, null);
it won't be null.
Here is a full example with simple methods on how to use the Android Keystore with pre-M and M Apis.
Comments
-
Donal Rafferty almost 2 years
I am trying to use the Android Key Store Provider that became available in Android 4.3 to securely save a Private Key and to then use this private key to encrypt and decode data.
I think I have implemented the correct approach and code for this so far however I am currently facing an odd issue that I cannot figure out.
I have a class called KeyStorage that I use to create the Key pair, load the KeyStore and retrieve the private key, the code for this class is as follows:
public class KeyStorage { public static final String ANDROID_KEYSTORE = "AndroidKeyStore"; private KeyStore keyStore; public void loadKeyStore() { try { keyStore = KeyStore.getInstance(ANDROID_KEYSTORE); keyStore.load(null); Enumeration<String> aliases = keyStore.aliases(); while(aliases.hasMoreElements()) Log.e("E", "Aliases = " + aliases.nextElement()); } catch (Exception e) { // TODO: Handle this appropriately in your app e.printStackTrace(); } } public void generateNewKeyPair(String alias, Context context) throws Exception { Calendar start = Calendar.getInstance(); Calendar end = Calendar.getInstance(); // expires 1 year from today end.add(1, Calendar.YEAR); KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context) .setAlias(alias) .setSubject(new X500Principal("CN=" + alias)) .setSerialNumber(BigInteger.TEN) .setStartDate(start.getTime()) .setEndDate(end.getTime()) .build(); // use the Android keystore KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA", ANDROID_KEYSTORE); gen.initialize(spec); // generates the keypair gen.generateKeyPair(); } public PrivateKey loadPrivteKey(String alias) throws Exception { if (keyStore.isKeyEntry(alias)) { Log.e("E", "Could not find key alias: " + alias); return null; } KeyStore.Entry entry = keyStore.getEntry(EnhancedCredentialStore.KEY_ALIAS, null); if (!(entry instanceof KeyStore.PrivateKeyEntry)) { Log.e("E", " alias: " + alias + " is not a PrivateKey"); return null; } return ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); }
I then have a class called CredentialStore that I try to use this in. I create an alias called "MySecureKey" and try to create and store a private key based on this. So as you can see I try to create the new Key pair based on the Alias load the keystore and then finally retrieve the Private key. However it doesn't work.
public class CredentialStore { public static final String KEY_ALIAS = "MySecureKey"; private KeyStorage KeyStorage; public CredentialStore(Activity context){ keyStorage = new KeyStorage(); try { keyStorage.generateNewKeyPair(KEY_ALIAS, context); } catch (Exception e) { e.printStackTrace(); } blueBirdKeyStorage.loadKeyStore(); try { keyStorage.loadPrivteKey(KEY_ALIAS); } catch (Exception e) { e.printStackTrace(); } }
I get the logs as follow:
Aliases = MySecureKey Could not find key alias: MySecureKey
So when I check the aliases in the loadKeyStore method it looks like it is there as it is coming back in the log. However when I try to call it using the loadKeyStore method I get the log saying it can not find the key "MySecureKey".
I cannot find any reason for this and researching online has proven unfruitful so I was wondering if anyone has any idea what might be going wrong?
-
Alexander Zhak over 9 years1. You generate KeyPair and don't make use of it. Your generateNewKeyPair method doesn't return anything. 2. You don't save anything to KeyStore to load it later. please refer to a sample on KeyStore useage. It might help you developer.android.com/samples/BasicAndroidKeyStore/index.html
-
Patrick over 7 years@AlexanderZhak altough the many upvotes, your comment is wrong: check out the official doc: developer.android.com/training/articles/… this is how you use the Android Keystore - it is not necessary to put the key explicitly if you use the KeyFactory with the Android Keystore instance.
-