Practically every smartphone that’s been released after 2013, has a fingerprint scanner. It has become so ubiquitous that any activity requiring some sort of confirmation in a mobile app relies on this feature.
This isn’t surprising as fingerprint scanners are unique and highly secure. They can be used for locking/unlocking devices and apps without needing to remember any passwords. They are much easier, faster, and cheaper to set up. Also, they make online transactions much more convenient as they allow you to tap the screen with your finger within a fraction of seconds. These are just a few reasons for implementing a fingerprint scanner for your project.
A Fingerprint Scanner will allow making your project much more secure and reliable!
So you came to the right place, as we’re the ones who have tons of expertise in implementing great projects. In this episode, we’ll teach you the basics of working with fingerprint scanner as well as how to implement it in a common Android application. Here we go!
Getting started with Fingerprint API
The ability to authenticate in third-party apps using your fingerprint was first introduced in the sixth version of Android and is called Fingerprint API.
In a nutshell, Fingerprint API allows you to replace the standard way of authentication using a passcode with a fingerprint scan, which, as we know, is much more secure in terms of personal data protection. Plus, it’s a neat time saving feature.
So how does it work? When you register in an application that relies on fingerprint scanning, it prompts you to enter a master password. The app will save the password, generating a crypto key which will be used to encrypt/decrypt the password. So the next time you will put your finger to the fingerprint scanner, the application will use the key to decrypt the password.
User data will be stored in an encrypted format. However, to implement this, you’ll need the following:
- an encryptor that will enable you to encrypt and decrypt the user password;
- crypto key to access the encryptor;
- a storage for crypto keys.
First, you need to specify the permission for using the sensor in the manifest. Since this permission isn’t “dangerous”, you may not check it during the application work.
To use the sensor, FingerprintAPI provides you with the classes FingerprintManager and FingerprintManagerCompat. Keep in mind, though, that when using FingerprintManagerCompat the hardware for fingerprint scanning may not be found. This is because this class verifies FEATURE_FINGERPRINT, which is not always specified by smartphone manufacturers.
Let’s begin by creating the FingerprintManager:
If you need to check whether the smartphone has a sensor using this piece of code:
After that, you need to check if there any existing fingerprints in the system:
And here is how you can check if the smartphone is protected with a password:
Now you can proceed to the next step.
In Android, crypto keys are stored in a specially protected place that makes it quite challenging for anyone with no access rights to extract them. This place is called KeyStore.
However, the KeyStore is used for storing only crypto keys, which means you can’t use it for storing passwords or private data. With that said, let’s initialize KeyStore:
The next step is implementing crypto keys. There are two ways you can do that:
- Symmetric key (KeyGenerator);
- A pair of public and private keys (KeyPairGenerator).
But which one should you choose? In our case, the application will encrypt the password upon the first log. Likewise, whenever the right fingerprint is scanned the app will decrypt the password. Thus, you’ll need a pair of public and private keys. The public key will be used to encrypt the password while the private key will be responsible for decrypting it when scanning the fingerprint.
Let’s initialize KeyPairGenerator:
Wherein KeyProperties.KEY_ALGORITHM_RSA is the encryption algorithm of the key and KEY_STORE is the name of the key storage.
Now that we’ve clarified which piece of code does what, let’s use KeyPairGenerator to create a pair of keys:
Wherein KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT is used to encrypt and decrypt the password.
.setUserAuthenticationRequired(true) allows you to verify a user with their fingerprint.
To verify that the key exists, the following line of code is used: sKeyStore.containsAlias(KEY_ALIAS)
Implementing the encryptor
The Cipher class allows you to encrypt/decrypt the key:
Wherein RSA is the encryption algorithm, ECB is the mode of operation, and OAEPWithSHA-256AndMGF1Padding is the addition.
Now let’s initialize it:
When using the encryptor in the mode Cipher.ENCRYPT_MODE you need a public key that prompts for user verification, so we’ll use this.
To decrypt Cipher.DECRYPT_MODE you need a private key that prompts for verification with a fingerprint.
Here are the encryption-decryption methods:
Fingerprint sensor implementation
In order to be able to use the sensor, you need the following method:
void authenticate(CryptoObject crypto, CancellationSignal cancel, int flags, AuthenticationCallback callback, Handler handler)
Wherein CancellationSignal allows you to cancel the process of fingerprint scanning and AuthenticationCallback returns the results of scanning.
For processing the results, use AuthenticationCallback:
That’s basically it, folks! Your code is good to go!
The implementation of fingerprint scanning will undoubtedly improve the user experience of your application. Hopefully, you found our article useful :) If you have any questions about the implementation or you want to put your project into the practice, feel free to write us.
The full project is available on the following GitHub page: https://github.com/MikhailLysyansky/FingerprintSample