Reputation: 11901
I want to store sensitive information like a login PIN. Today with EncryptedSharedPreferences (ESP) one can argue that's enough. But let's say I want to offer the possibility to use Biometrics. This google sample show us how to use BiometricPrompt.CryptoObject
for data encryption and decryption.
But this raises one question:
Should I save the PIN in ESP without adding another layer of security?
If so, the Biometric prompt will act like a faster and convenient way for inserting the PIN. I just have to listen for the onAuthenticationSucceeded
ignoring the result: BiometricPrompt.AuthenticationResult
and assume the user is logged (or perform a API login with the PIN value saved in ESP). If I save the PIN in ESP but with an extra layer of security provided by the encryption of the CryptographyManager
(cryptographyManager.encryptData
/ cryptographyManager.decryptData
) I'll run into trouble when the user inserts the PIN manually, because I'll have no way to encrypt the inserted data and compare with the encrypted stored one. In this scenario I'll not have a Cipher
object since there's no BiometricPrompt
(let's say I want to offer the possibility for offline login).
Maybe I'm missing a step here, but is it enough to store the PIN in ESP and use only the Biometrics for "handy login"?
Upvotes: 2
Views: 2923
Reputation: 4438
i made a library to do exactly this:
This library use livedata to merge androidx.security with androidx.biometric using setUserAuthenticationRequired
https://github.com/xanscale/LocalhostToolkit/tree/master/security
You can just use this inside fragment or activity
BiometricEncryptedSharedPreferences.create(
this,
"secret_shared_prefs",
1,
new BiometricPrompt.PromptInfo.Builder().setTitle(getString(R.string.app_name)).setDeviceCredentialAllowed(true).build()
).observe(this, it -> {
it.edit().putString("secretValue", "IT works!").apply();
System.out.println(it.getString("secretValue", "It didn't work"));
});
Upvotes: 1
Reputation: 58507
The keys that encrypt your encrypted shared preferences are in turn encrypted with a master key. MasterKeys.getOrCreate
takes a KeyGenParameterSpec
as its input.
Instead of just using the predefined MasterKeys.AES256_GCM_SPEC
you can build your own KeyGenParameterSpec
with the settings you want, e.g. specifying that user authentication should be required.
See the points under "For use cases requiring additional security, complete the following steps" here.
Upvotes: 2