Authentication Using Fingerprint in Android - GeeksforGeeks

20 Dec, 2021
Fingerprint authentication came with Android 6.0 (Marshmallow), with the newly released APIs allowing users to authenticate their smartphones with fingerprint sensors. In order to authenticate users using fingerprint sensors we need the instance of FingerprintManager class and call the authenticate() method. Also, we should take care of the devices that must have fingerprint sensors.
Advantages of using fingerprint authentication:
Fast, Reliable, and Ease to use
High security as each individual has unique fingerprints
Most importantly, it doesn’t matter that you are physically or medically fit or not able to remember your password, fingerprints are always faultless
In this example, we will build an application that asks for users’ fingerprints to authenticate and if the users enter the correct fingerprint then they are allowed to enter into the application.
Step by Step Implementation
Step 1: Create a new project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language. Make sure while creating a new android project you set the minimum API level to be 23 (Android 6.0).
Step 2: Permission required
In order to use fingerprint authentication, we need to the permission USE_FINGERPRINT to our AndroidMainfest.xml file.
XML
<?xml version="1.0" encoding="utf-8"?><manifest>       <uses-permission android:name="android.permission.USE_FINGERPRINT" /></manifest>
Before moving further let’s add some color attributes for our application in the colors.xml file.
XML
<resources>    <color name="colorPrimary">#0F9D58</color>    <color name="colorPrimaryDark">#16E37F</color>    <color name="colorAccent">#03DAC5</color>    <color name="black">#000</color></resources>
Step 3: Creating image assets
In this step, we will create an image asset for fingerprint. Go to drawable > right-click  > New > Vector Asset > Clip Art and search for fingerprint and add it to the drawable folder.
Step 4: Creating fingerprint layout
Now, we will create the layout for our fingerprint sensor. Go to activity_main.xml and copy the following code.
XML
<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    android:orientation="vertical"    android:background="@color/colorAccent"    tools:context=".MainActivity">      <ImageView        android:layout_width="72dp"        android:layout_height="72dp"        android:layout_margin="8dp"        android:src="@drawable/ic_fingerprint" />      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:gravity="center"        android:textColor="#000"        android:layout_margin="8dp"        android:text="One Touch Sing In"/>      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:gravity="center"        android:textColor="#000"        android:layout_margin="8dp"        android:text="Please place user finger for authentication"/>      <TextView        android:id="@+id/textMsg"        android:textColor="#000"        android:layout_width="match_parent"        android:gravity="center"        android:textAppearance="@style/TextAppearance.AppCompat.Large"        android:layout_margin="8dp"        android:layout_height="wrap_content"/>  </LinearLayout>
Step 5: Working with MainActivity.java file
In this step, we will introduce our FingerprintManager class and initialize it. We will use generateKey() method which will generate an encryption key that is stored securely on the device, we will also use cipherInit() method which initialized the cipher that will be used to create the encrypted FingerprintManager. Below is the code for the MainActivity.java file.
Java
package com.paulsofts.gfgfingerprintauthentication;  import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;  import android.Manifest;import android.annotation.TargetApi;import android.app.KeyguardManager;import android.content.pm.PackageManager;import android.hardware.fingerprint.FingerprintManager;import android.os.Build;import android.os.Bundle;import android.security.keystore.KeyGenParameterSpec;import android.security.keystore.KeyPermanentlyInvalidatedException;import android.security.keystore.KeyProperties;import android.widget.TextView;  import java.io.IOException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.UnrecoverableKeyException;import java.security.cert.CertificateException;  import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;  public class MainActivity extends AppCompatActivity {      private KeyStore keyStore;    // Defining variable for storing      // key in android keystore container    private static final String KEY_NAME = "GEEKSFORGEEKS";    private Cipher cipher;    private TextView errorText;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);          // Initializing KeyguardManager and FingerprintManager        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);        FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);          // Initializing our error text        errorText = (TextView) findViewById(R.id.errorText);          // Here, we are using various security checks        // Checking device is inbuilt with fingerprint sensor or not        if(!fingerprintManager.isHardwareDetected()){              // Setting error message if device             // doesn't have fingerprint sensor            errorText.setText("Device does not support fingerprint sensor");        }else {            // Checking fingerprint permission            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {                errorText.setText("Fingerprint authentication is not enabled");            }else{                // Check for at least one registered finger                if (!fingerprintManager.hasEnrolledFingerprints()) {                    errorText.setText("Register at least one finger");                }else{                    // Checking for screen lock security                    if (!keyguardManager.isKeyguardSecure()) {                        errorText.setText("Screen lock security not enabled");                    }else{                          // if everything is enabled and correct then we will generate                        // the encryption key which will be stored on the device                        generateKey();                        if (cipherInit()) {                            FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);                            FingerprintHandler helper = new FingerprintHandler(this);                            helper.startAuth(fingerprintManager, cryptoObject);                        }                    }                }            }        }    }        @TargetApi(Build.VERSION_CODES.M)    protected void generateKey() {        try {            keyStore = KeyStore.getInstance("AndroidKeyStore");        } catch (Exception e) {            e.printStackTrace();        }            KeyGenerator keyGenerator;        try {            keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {            throw new RuntimeException("KeyGenerator instance failed", 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);        }    }        @TargetApi(Build.VERSION_CODES.M)    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("Cipher failed", 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("Cipher initialization failed", e);        }    }}
Step 6: Create Fingerprint Authentication Handler class
In this step, we will create a FingerprintHandler.java class and extends FingerprintManager.AuthenticationCallback and override the methods and provide our definitions. Below is the code of FingerpirntHandler class.
Java
import android.Manifest;import android.app.Activity;import android.content.Context;import android.content.pm.PackageManager;import android.hardware.fingerprint.FingerprintManager;import android.os.CancellationSignal;import android.widget.TextView;  import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;  public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {      private Context context;      // Constructor    public FingerprintHandler(Context mContext) {        context = mContext;    }      // Fingerprint authentication starts here..    public void Authentication(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) {        CancellationSignal cancellationSignal = new CancellationSignal();        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {            return;        }        manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);    }      // On authentication failed    @Override    public void onAuthenticationFailed() {        this.update("Authentication Failed!!!", false);    }      // On successful authentication    @Override    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {        this.update("Successfully Authenticated...", true);    }      // This method is used to update the text message    // depending on the authentication result    public void update(String e, Boolean success){        TextView textView = (TextView) ((Activity)context).findViewById(R.id.textMsg);        textView.setText(e);        if(success){            textView.setTextColor(ContextCompat.getColor(context,R.color.black));        }    }}
Output: 
We will test our application on a device that supports a fingerprint sensor. Here, firstly we entered the incorrect finger and we get the Authentication failed message, and then we will enter the correct finger.
Picked
Android
Java
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Flutter - Custom Bottom Navigation Bar
How to Read Data from SQLite Database in Android?
How to Post Data to API using Retrofit in Android?
Android Listview in Java with Example
Retrofit with Kotlin Coroutine in Android
Arrays in Java
Split() String method in Java with examples
For-each loop in Java
Reverse a string in Java
Arrays.sort() in Java with examples