I am investigating the use of the Android KeyStore for Marshmallow and above.
I would like to simultaneously verify both the data integrity and the authentication of my data by employing HMAC's.
How do I go about achieving this?
I am current generating an Encrypt/Decrypt key as follows:-
mKeyStore = KeyStore.getInstance(keyStoreName);
mKeyStore.load(mKeyStoreLoadStoreParameter);
if (mKeyStore.containsAlias(keyStoreAlias)) {
mSecretKey = (SecretKey) mKeyStore.getKey(keyStoreAlias, KEY_STORE_PASSWORD);
} else {
final KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, keyStoreName);
final int keyPurpose = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT;
keyGenerator.init(
new KeyGenParameterSpec.Builder(keyStoreAlias, keyPurpose)
.setKeySize(KEY_STORE_KEY_SIZE)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setRandomizedEncryptionRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
mSecretKey = keyGenerator.generateKey();
I have found this sample for generating HMAC's
SecretKey key = ...; // HMAC key of algorithm "HmacSHA512".
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
keyStore.setEntry(
"key1",
new KeyStore.SecretKeyEntry(key),
new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build());
// Key imported, obtain a reference to it.
SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
// The original key can now be discarded.
Mac mac = Mac.getInstance("HmacSHA512");
mac.init(keyStoreKey);
However, how do I use this when encrypting/decrypting my data?
EXPLANATION
I have a number of choices/decisions to make when implementing security/cryptography within any Android application.
1). Do I implement cryptography of any sort Yes or No? 2). If Yes then... I should attempt to achieve the "most" secure solution possible.
If I am going to employ cryptography then I need to ensure the following.
a). I store passwords/secret keys in a "Safe Place" e.g. Android Key Store. b). I use the "strongest" cryptography available. c). I would like to simultaneously verify both the data integrity and the authentication of my data, e.g. I would like to detect if my encrypted data has been tampered with.
As I understand what I have read about HMAC's, they provide this functionality. I would like to know how I code the use of HMAC's into my Android application to ensure both the data integrity and the authentication of my data.
You can apply HMAC to the plain text HMAC(plain text)
before encrypting and recompute the HMAC after decrypting to check that the original message is the same.
It may be redundant because if the cipher text is altered you will not be able to decrypt it.
First generate a HMAC key inside AndroidKeyStore
. I found an example here
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_HMAC_SHA256, "AndroidKeyStore");
keyGenerator.initialize(
new KeyGenParameterSpec.Builder(hmacKeyAlias, KeyProperties.PURPOSE_SIGN).build());
SecretKey key = keyGenerator.generateKey();
Then Apply HMAC to the original data and store the result somewhere
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
byte hmacOriginalData[] = mac.doFinal(dataToEncrypt);
//Store hmacOriginalData
After decrypting, get HMAC key from AndroidKeyStore, recompute HMAC and check both macs are equal
Key key = keyStore.getKey(hmacKeyAlias, null);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
byte hmacDecryptedData[] = mac.doFinal(decryptedData);
//Check equals(hmacDecryptedData, hmacOriginalData);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With