Reputation: 53
Security is not my area of expertise but I have a question regarding storing a secret key in the Android KeyStore using API 18 and above. I use the following code to try and store my key:
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.SecretKeyEntry sKeyEntry = new KeyStore.SecretKeyEntry(ivKey);
ks.setEntry(ALIAS, sKeyEntry, null); // This is where the issue is
I understand that "null" should be a KeyProtection param that I build but this isn't available for API 18. Is there a workaround for this issue? I have been having difficulty finding anything that works.
EDIT I should mention that leaving it as null throws the error:
java.security.KeyStoreException: Protection parameters must be specified when importing a symmetric key
Upvotes: 4
Views: 5605
Reputation: 2874
For creating a RSA(Public/Private) key using AndroidKeyStore you can use following methods.
Getting a KeyStore
val keyStore = KeyStore.getInstance("AndroidKeyStore")
keyStore.load(null)
Check if KeyStore contains our key or not
If KeyStore does not contains key, then create keys
if (!keyStore.containsAlias(KEY_NAME)) {
val keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
keyPairGenerator.initialize(
KeyGenParameterSpec.Builder(
KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
.setAlgorithmParameterSpec(RSAKeyGenParameterSpec(2048, F4))
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
.build()
)
val keyPair = keyPairGenerator.generateKeyPair()
val publicKey = keyPair.public
val privateKey = keyPair.private
}
Retrieve keys using KEY_NAME
val privateKeyEntry = keyStore.getEntry(KEY_NAME, null) as KeyStore.PrivateKeyEntry
val privateKey = privateKeyEntry.privateKey
val publicKey = privateKeyEntry.certificate.publicKey
For more information you can refer this:
Upvotes: 0
Reputation: 5032
AndroidKeyStore did not support secret keys until API level 23. To do what you're trying to do you have to target 23 or above.
What you could do is use AndroidKeyStore's support for public/private key pairs (e.g. RSA) to encrypt the secret key material, then store it in a local file. When you want to use it, you'd need to use the private key to decrypt it, then once you have the key material use the normal Java crypto APIs (i.e. don't specify "AndroidKeyStore") to do cipher operations with it.
To see how to use AndroidKeyStore RSA key pairs to encrypt and decrypt, take a look at http://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/
However, I don't think that actually achieves anything from a security perspective. What security goals are you trying to achieve?
Upvotes: 1