I would like to use the Hardware Android Keystore, to safely encrypt sensitiv data and store it locally on the device. The standard implementation seems very easy and there are enough tutorials out there on how to implement it.
But the requirements I got require that a user provided secret (a user pin or password that the user has to enter) is included into the encryption of the senstive data. So that encryption/decryption of the data only works with the known user secret and not without it.
I haven't found a way to provide a user secret into the Android Keystore process.
How can I encrypt/decrypt data with the Android Keystore that needs a secret user input to actually work?
AndroidKeyStore
does not provide any API to set user provided password for the generated secret. Only thing that you can do is, setting a KeyGenParameterSpec.Builder#setUserAuthenticationRequired flag to true
for system provided user authentication (pin / pattern / fingerprint etc.. )
The real power of AndroidKeyStore
is comes from the TEE and Secure Hardware. So that, any other option rather than using the key directly in the AndroidKeyStore
should be considered as less-secure. So that, generating PBKDF2 using both user provided secret and key store encrypted secret doesn't makes your encryption more secure. Because, that new key should be managed in an application memory and is vulnerable (of course in compromised device) until you complete encryption and wipe all of the key bytes.
But in secure hardware, AndroidKeyStore
doesn't even loads your keys in a memory. Every operation happens in a separated secure hardware.
If your requirement is not strictly "having one key" and "encrypt data only once", you may consider to encrypt your data twice using both of the secret from AndroidKeyStore
and user key which is derived from user password.
And also, you may want to read this paper: http://www.cs.ru.nl/~joeri/papers/spsm14.pdf. In this paper, authors also mention Bouncy Castle keystore with user-provided password.