All CategoriesAndroid App Development

How to Implement Fingerprint Authentication in Android

Introduction to Fingerprint

Fingerprint Authentication is a new feature of security which has been added to Android devices from Android 6.0 (Marshmallow).
It uses touch sensor in our devices (means this sensor is necessary for fingerprint authentication) and identifies the user fingerprints. The fingerprints provide us the access to the device and the functionalities of the apps.
To create a Fingerprint Authentication project, we must handle the authentication process. This we do with the help of FragmentManager class. To perform encryption process, it involves key, cipher, and key storage.

Classes:

FingerprintManager:

It is a class which comes from android.hardware.fingerprint.FingerprintManager. We have to create its nested class i.e. FingerprintManager.AuthenticationCallback which is used to implement the callback methods. we override these methods in our class.

KeyGenerator:

It is a class which is used to generate the key and store it in the Keystore container. The Keystore container is a storage area which is used for the secure storage of cryptographic keys in the Android devices.

KeygaurdManager:

It is a class which is used to lock and unlock the keyboard. By getting the instance of this class we will check whether the keyguard is secure or not.

Cipher:

It is the class which provides the functionality of cryptographic cipher for encryption and decryption. Here, we use the instance of this class to create a cryptoObject and assign it to the FingerprintManager instance.
Now, let us use these classes in our application and override its callback methods.

Configure Fingerprint Authentication in our device:

It is very simple to configure this security in our device. Just follow the simple steps:
Go to Settings and select the Security option. Next select Fingerprint, it will ask for a backup security like pin, pattern etc, for locking the screen before registering the fingerprint security. After this, it goes to the detection screen. So use the touch sensor of our device; we must move the finger till it is registered successfully.

Example with code:

Create an Application FingerprintAuthenticationExampleAndroid.

Requirements:

Before Creating this application, we have to add the permission of Fingerprint in AndroidManifest.xml file. And minimum API level 23.
 

<uses-permission android:name="android.permission.USE_FINGERPRINT" />

FingerPrintHandler.java, MainActivity.java, activity_main.xml.
Let’s do it.

activity_main.xml:

This is our Main Layout file which shows an ImageView of Fingerprint and a TextView. This shows the status whether the user authentication failed or succeeded, whether it is registered or not.
Add the code inside RelativeLayout element.
 

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_fp_40px"
android:id="@+id/iv_Fingerprint"
android:layout_centerInParent="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_Fingerprint"
android:text="Touch Sensor"
android:layout_centerHorizontal="true"/>

 
Here, we can see and set the properties accordingly.

MainActivity.java:

This is our Main Activity. Here we will implement all the classes which are discussed above.

Initialize:

private FingerprintManager fingerprintManager;
private KeyguardManager keyguardManager;
private KeyStore keyStore;
private KeyGenerator keyGenerator;
private static final String KEY_NAME = "example_key";
private Cipher cipher;
private FingerprintManager.CryptoObject cryptoObject;

 
Firstly, we will get the reference of our system services i.e. FingerprintManager and KeygaurdManager.
Add the code in onCreate(){..}:

keyguardManager =
(KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager =
(FingerprintManager) getSystemService(FINGERPRINT_SERVICE);

 
Now, it will check the security of backup screen, unlock the permission of using fingerprint and registered fingerprints in the device. If there are no fingerprints registered then it will show the toast message to register at least one fingerprint.
 

Add the code here:

if (!keyguardManager.isKeyguardSecure()) {
Toast.makeText(this,
"Lock screen security not enabled in Settings",
Toast.LENGTH_LONG).show();
return;
}
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.USE_FINGERPRINT) !=
PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,
"Fingerprint authentication permission not enabled",
Toast.LENGTH_LONG).show();
return;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
// This happens when no fingerprints are registered.
Toast.makeText(this,
"Register at least one fingerprint in Settings",
Toast.LENGTH_LONG).show();
return;
}

 
Now, we will have to access the Keystore and generate the key which will later be stored by Android Keystore system. By using an instance of KeyGenerator service we will generate the key.
So, Add the code for this by implementing a method generateKey().
 

protected void generateKey() {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
} catch (Exception e) {
e.printStackTrace();
}
try {
keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES,
"AndroidKeyStore");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
throw new RuntimeException(
"Failed to get KeyGenerator instance", e);
}
try {
keyStore.load(null);
keyGenerator.init(new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();
} catch (NoSuchAlgorithmException |
InvalidAlgorithmParameterException
| CertificateException | IOException e) {
throw new RuntimeException(e);
}

 
Now, next step is to initialize the Cipher which is used to create CryptoObject instance. It will later be used in the Authentication process.
So, Add the code for this by implementing a method cipherInit():
 

public boolean cipherInit() {
try {
cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
try {
keyStore.load(null);
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
null);
cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (KeyStoreException | CertificateException
| UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}

 
Add the Code for CryptoObject instance in onCreate():
 

if (cipherInit()) {
cryptoObject =
new FingerprintManager.CryptoObject(cipher);
FingerPrintHandler helper = new FingerPrintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}

 

FingerPrintHandler.java:

Create this class and extend it with FingerprintManager.AuthenticationCallback. It is a class which handles the callback events. This means we will know about the authentication status with the help of this class and its overriding methods.

Add the code here:

// generate constructor of FingerprintHandler class.
This method is called to initiate Fingerprint Authentication. It must pass both the instances i.e. FingerprintManager and CryptoObject. It also checks again for the permission.
public void startAuth(FingerprintManager manager,
 

FingerprintManager.CryptoObject cryptoObject) {
cancellationSignal = new CancellationSignal();
if (ActivityCompat.checkSelfPermission(appContext,
Manifest.permission.USE_FINGERPRINT) !=
PackageManager.PERMISSION_GRANTED) {
return;
}
manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
}

 
When an unregistered fingerprint tries for the authentication then this method is called and it shows the message that Authentication failed.

@Override
public void onAuthenticationFailed() {
Toast.makeText(appContext,
"Authentication failed.",
Toast.LENGTH_LONG).show();
}

Android Programming
When a registered fingerprint tries for authentication, This method is called and it shows the message that Authentication succeeded.

@Override
public void onAuthenticationSucceeded(
FingerprintManager.AuthenticationResult result) {
Toast.makeText(appContext,
"Authentication succeeded.",
Toast.LENGTH_LONG).show();
}

 
Similarly, we can override other methods like onAuthenticationError() and onAuthenticationHelp().

Output:

                                                                                     If not Registered

Registered Fingerprint


Unregistered fingerprint

Download Code: GitHub

Conclusion:

Here, in this example, we saw a practical implementation of Fingerprint Authentication in Android. It involves the keys, key storage, cipher’s, and some system services like FingerprintManager etc. As we discussed above by using some callbacks methods we can inform the user whether the fingerprint is registered or not. If registered, show ‘succeeded’ otherwise show ‘authentication failed’. This is a very important feature for security in Android.

Android Programming

Tags

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related Articles

Close