Android Fingerprint Authentication

Aitor Viana
Jul 10, 2016 · 3 min read
Image for post
Image for post

Let’s be frank, I don’t like authenticating, you don’t like authenticating, users don’t like authenticating.
Every time my phone asks me to enter a password, even a pattern, I feel like I want to punch an elephant.

What we (users) normally want is to take out our device and use it immediately, we want access to our information in no-time, anything else is just not good enough for us.
How many of us have disabled in the past the lock screen of our device and, left it completely open and vulnerable to undesired hands just because we did not want to spend time entering a password. As simple as that, we are very lazy people.
If we’re capable of compromising our entire device’s security just to have a slightly faster user experience, image what we’re capable of doing to an app that pops a dialog to enter a password every time it decides we need to be authenticated to perform a certain action.

Android fingerprint authentication was introduced on M release and Nexus phones — today available in many more device brands — to solve that problem. It encourages users to use authentication in a very non-disturbing and easy way so that we don’t need to compromise between security and user experience.

Imagine you are developing an app that requires to perform some critical operation like, payment. You want to be sure that your user is authenticated prior wiring any kind of money, right?
Fingerprint authentication is your ally. Let’s go through the main elements you will need to achieve such functionality.

The key

Create a key and bind it to a fingerprint authentication.

int purpose = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT;// to make it harder, byte padding
int padding = KeyProperties.ENCRYPTION_PADDING_PKCS7;
// Init the generator
keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, purpose)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
// key allowed only when user is authenticated
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(padding)
.build());
// generate the key
keyGenerator.generateKey();

The KEY_NAME (aka key alias) is used to reference and find the generated key. The call to setUserAuthenticationRequired(true) binds the key to the user authentication.
You could also set the time validity of the key since the last authentication using setUserAuthenticationValidityDurationSeconds(int) in the builder object.

We can now get the key from the key store using the KEY_NAME as reference.

The Cipher

The cipher is the component that provides the functionality for encryption and decryption. We can create a cipher using the Cipher.getInstance(String) method. The String identifies the transformation the cipher will perform e.g., DES/CBC/PKCS5Padding.

// init the cipher
SecretKey secretKey = (SecretKey)keyStore.getKey(keyName, password);
mCipher.init(Cipher.ENCRYPT_MODE, secretKey);

The Authentication

The authentication is fairly simple, just get a reference to the FingerprintManager and call the authenticate() using an initialized cipher.

mFingerprintManager.authenticate(
new FingerprintManager.CryptoObject(mCipher), mCancellationSignal,
0 /* flags */,
new FingerprintManager.AuthenticationCallback() {
public void onAuthenticationSucceeded() {
// do the payment here...
}
}, null);

The Pitfalls

The call mCipher.init() will throw InvalidKeyException when the key is no longer valid because, e.g. new fingerprints have been added or removed since last authentication, device rebooted, etc.
In this case, it is good practice to fallback to e.g. password authentication to verify your user is who he/she should be.
On succesful password authentication, you could recreate the key calling mKeyGenerator.generateKey() and continuing with fingerprint authentication for subsequent operations.

The Code

What discussed in this post is implemented one way or another inside the FingerLock library available on GitHub.
The library hides all the complexity of creating and initializing a key store, a cipher, checking key validity, etc. and reduces fingerprint authentication to a handful of calls and callbacks.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store