Saturday, December 28, 2024
Google search engine
HomeLanguagesJavaAuthentication Using Fingerprint in Android

Authentication Using Fingerprint in Android

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

Example

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: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.

RELATED ARTICLES

Most Popular

Recent Comments