Android How to add Fingerprint Authentication | Biometric Authentication Tutorial

In this tutorial, we will learn how to implement Fingerprint or Biometric Authentication in Android Application.

Don't Miss

To authenticate the user using fingerprint sensor, we must need to get an instance of the newly implemented FingerprintManager class and call the authenticate() method. Most of the device not supported in fingerprint sensor and it is working on above API 23.

We are going to create a new android project. Go to File ⇒ New ⇒ New Projects in Android studio and set the minimum SDK version to API 23: Android 6.0(Marshmallow).

Add Permission

To authenticate user, we need to add USE_FINGERPRINT permission in AndroidManifest.xml file.

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

Adding Layout

Adding below code in activity_main.xml file. click here to Download Fingerprint icon image.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="in.studytutorial
           .androidfingerprintauthentication.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:id="@+id/headerLayout"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_marginTop="100dp"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/ic_fp"
            android:paddingTop="2dp"
            android:layout_marginBottom="30dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#000"
            android:textSize="16sp"
            android:textAlignment="center"
            android:gravity="center"
            android:id="@+id/desc"
            android:text="Please place your fingertip
                  on the scanner to verify your identity"
            android:layout_margin="16dp"
            android:paddingEnd="30dp"
            android:paddingStart="30dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/errorText"
            android:textSize="14sp"
            android:textAlignment="center"
            android:id="@+id/errorText"
            android:paddingEnd="30dp"
            android:paddingStart="30dp"
            android:layout_marginTop="30dp"
            android:gravity="center"/>

    </LinearLayout>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000"
        android:textSize="14sp"
        android:text="(Your device should have at
         least one fingerprint registered in device settings)"
        android:layout_marginLeft="16dp"
        android:textAlignment="center"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="26dp"
        android:layout_alignParentBottom="true"/>
</RelativeLayout>

Create Another Activity

After successfully authentication, we will start another activity. Hence we need to create a new Activity named as HomeActivity. Add below code in acitivity_home.xml file

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="in.studytutorial
           .androidfingerprintauthentication.HomeActivity">

    <TextView
        android:layout_width="match_parent"
        android:text="Welcome To Home Activity"
        android:layout_centerVertical="true"
        android:textSize="24sp"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:text="You have successfully authenticate
          with fingerprint"
        android:layout_alignParentBottom="true"
        android:textSize="14sp"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"/>

</RelativeLayout>

Creating Fingerprint Authentication Handler Class

We will create a new java class names as FingerprintAuthenticationHandler. It will use to handle authentication response. This class extends FingerprintManager.AuthenticationCallback and include some addition function. Use the below code

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.widget.TextView;

public class FingerprintAuthenticationHandler extends
                      FingerprintManager.AuthenticationCallback {

    private Context context;

    // Constructor
    public FingerprintAuthenticationHandler(Context mContext) {
        context = mContext;
    }

    public void startAuth(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);
    }

    @Override
    public void onAuthenticationError(int errMsgId, CharSequence errString) {
        this.update("Fingerprint Authentication error\n" + errString, false);
    }

    @Override
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
        this.update("Fingerprint Authentication help\n" + helpString, false);
    }

    @Override
    public void onAuthenticationFailed() {
        this.update("Fingerprint Authentication failed.", false);
    }

    @Override
    public void onAuthenticationSucceeded(
             FingerprintManager.AuthenticationResult result) {
        this.update("Fingerprint Authentication succeeded.", true);
    }

    public void update(String e, Boolean success){
        TextView textView = (TextView) ((Activity)context)
           .findViewById(R.id.errorText);
        textView.setText(e);
        if(success){
            textView.setTextColor(ContextCompat.getColor(context,
               R.color.colorPrimaryDark));
            Intent i = new Intent(context, HomeActivity.class);
            context.startActivity(i);
        }
    }
}

MainAcivity Class

We have already create MainActivity.class. In this class, we will implemented some method which used to check hardware capability, generate encrypt key, create the encrypted FingerprintManager and authentication process.

We will be Initialize both Android Keyguard Manager and Fingerprint Manager. Keyguard Manager is used to check lock screen security enabled in the setting. Fingerprint Manager is used to check hardware capability. Also create some below method:

  • generateKey() function which generates an encryption key which is then stored securely on the device.
  • cipherInit() function that initializes the cipher that will be used to create the encrypted FingerprintManager.
  • CryptoObject instance and various other checks before initiating the authentication process which is implemented inside onCreate() method.

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.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
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;
    // Variable used for storing the key in the Android Keystore container
    private static final String KEY_NAME = "studytutorial";
    private Cipher cipher;
    private TextView textView;
    public KeyguardManager keyguardManager;
    public FingerprintManager fingerprintManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initializing both Android Keyguard Manager and Fingerprint Manager
        keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
        fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);

        textView = (TextView) findViewById(R.id.errorText);

        checkFingerPrintScanner();

    }

    protected void checkFingerPrintScanner(){
        // Check whether the device has a Fingerprint sensor.
        if(!fingerprintManager.isHardwareDetected()){
            /**
             * An error message will be displayed if the device does not contain the fingerprint hardware.
             * However if you plan to implement a default authentication method,
             */
            textView.setText("Your Device does not have a Fingerprint Sensor");
        }else {
            // Checks whether fingerprint permission is set on manifest
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
                textView.setText("Fingerprint authentication permission not enabled");
            }else{
                // Check whether at least one fingerprint is registered
                if (!fingerprintManager.hasEnrolledFingerprints()) {
                    textView.setText("Register at least one fingerprint in Settings");
                }else{
                    // Checks whether lock screen security is enabled or not
                    if (!keyguardManager.isKeyguardSecure()) {
                        textView.setText("Lock screen security not enabled in Settings");
                    }else{
                        generateKey();

                        if (cipherInit()) {
                            FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher);
                            FingerprintAuthenticationHandler helper = new FingerprintAuthenticationHandler(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("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);
        }
    }

    @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("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);
        }
    }
}

2 COMMENTS

Leave a Reply to marcial_paz Cancel reply

Please enter your comment!
Please enter your name here

564FansLike

Recent Posts

Concept of Session in Laravel Tutorial

Sessions are used to store details about the user throughout the requests. Laravel supplies various drivers like file, cookie, apc, array, Memcached, Redis, and database to handle session data. By default, file driver is used as a result of it's light-weight....

Laravel Url Generation Tutorial

Our web application revolves around routes and URLs. After all, they're what direct our users to our pages. At the end of the day, serving pages is what any web application should do. Our users may...

Concept of Laravel Views Tutorial

In MVC framework, the letter "V" stands for Views. It separates the application logic and presentation logic. Views are saved in resources/views listing. Generally, the view contains the HTML which might be served by the application.

Related Articles

Concept of Session in Laravel Tutorial

Sessions are used to store details about the user throughout the requests. Laravel supplies various drivers like file, cookie, apc, array, Memcached, Redis, and database to handle session data. By default, file driver is used as a result of it's light-weight....

Laravel Url Generation Tutorial

Our web application revolves around routes and URLs. After all, they're what direct our users to our pages. At the end of the day, serving pages is what any web application should do. Our users may...

Concept of Laravel Views Tutorial

In MVC framework, the letter "V" stands for Views. It separates the application logic and presentation logic. Views are saved in resources/views listing. Generally, the view contains the HTML which might be served by the application.
WP2Social Auto Publish Powered By : XYZScripts.com