How to add fingerprint authentication to android application

Android finger print authentication is one of the amazing feature introduced by android with the release of Marshmallow. Finger print authentication is the smoothest way of authention.The user just need to scan his/her finger on hardware instead of remembering the pin ,pattern or password code. Mostly all new phones are having this fingerprint authentication as lock screen. In the same way this technology can be used inside your application also. In this tutorial we will learn how to  add fingerprint authentication to android application.

Steps

  1. Create new project in android studio
  2. Implement the fingerprint helper class
  3. Create layout with finger print icon
  4. Implementing java code
  5. Add the required features and permissions to AndroidManifest.xml

Create new project in android studio

Refer Android beginners app development guide if you are beginner or if you don’t know how to create project in android studio.

Implement the fingerprint helper class

In this step you need to create one java file under java/your-package/ using the following class name. This class will be from FingerprintManager.AuthenticationCallback class which will implement the methods for authenticating the fingerprint of the user.

import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.Build;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;

@TargetApi(Build.VERSION_CODES.M)
public class FPHandler extends FingerprintManager.AuthenticationCallback {

private CancellationSignal cancellationSignal;
private Context context;

public FPHandler(Context mContext) {
context = mContext;
}

public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) {

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) {

Toast.makeText(context, "Fingerprint Authentication error" + errString, Toast.LENGTH_LONG).show();
}

@Override

public void onAuthenticationFailed() {
Toast.makeText(context, "Fingerprint Authentication failed", Toast.LENGTH_LONG).show();
}

@Override
public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Toast.makeText(context, "Fingerprint Authentication help" + helpString, Toast.LENGTH_LONG).show();
}
@Override
public void onAuthenticationSucceeded(
FingerprintManager.AuthenticationResult result) {

//here you can authorise the user to use the application .
Toast.makeText(context, "Fingerprint Authentication sucess", Toast.LENGTH_LONG).show();
}

}

Create layout with finger print icon

In this step you need to design the screens for the finger print authentication screen . Here i am just giving an imageview with icon picked from material design icons of google. You can have you own screen based on your requirement.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.codesfor.fingerprintapp.MainActivity"
tools:showIn="@layout/app_bar_main">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_fingerprint_black_24dp"
android:id="@+id/imageView"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="36dp" />

</android.support.constraint.ConstraintLayout>

Implementjava code

In this step we will create the fingerprint authentication activity. There are few criteria to met for adding fingerprint in your application. First of all the user needs to have finger print hardware. If not you need to have an alternate authentication mechanism. The user needs to be registered with at least one finger print in his device settings . The following class will check whether this requirements are there before going for fingerprint authentication.

import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.app.KeyguardManager;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.Manifest;
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.widget.Toast;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
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 static final String KEY_NAME = "codesfor";
KeyStore fingerprint_keyStore;
KeyGenerator fingerprint_keyGenerator;
FingerprintManager fingerprint_Manager;
KeyguardManager fingerprint_keyguardManager;
Cipher fingerprint_cipher;
FingerprintManager.CryptoObject fingerprint_cryptoObject;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

fingerprint_keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprint_Manager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);

if (!fingerprint_Manager.isHardwareDetected()) {

Toast.makeText(getApplicationContext(),"This device does not have finger print support",Toast.LENGTH_SHORT).show();

}else if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {

Toast.makeText(getApplicationContext(),"Permission not granted",Toast.LENGTH_SHORT).show();

}else if (!fingerprint_Manager.hasEnrolledFingerprints()) {

Toast.makeText(getApplicationContext(),"You need to configure finger print in your device settings first",Toast.LENGTH_SHORT).show();

}else if (!fingerprint_keyguardManager.isKeyguardSecure()) {

Toast.makeText(getApplicationContext(),"You need to configure finger print in your device settings first",Toast.LENGTH_SHORT).show();

} else {
try {

generatefingerprintKey();

} catch (FingerprintException e) {
e.printStackTrace();
}

if (InitialiseCipher()) {
fingerprint_cryptoObject = new FingerprintManager.CryptoObject(fingerprint_cipher);
FPHandler helper = new FPHandler(this);
helper.startAuth(fingerprint_Manager, fingerprint_cryptoObject);
}
}
}
}

@RequiresApi(api = Build.VERSION_CODES.M)
public boolean InitialiseCipher() {
try {
fingerprint_cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException e) {
throw new RuntimeException("Initialisation Failed", e);
}

try {
fingerprint_keyStore.load(null);
SecretKey key = (SecretKey) fingerprint_keyStore.getKey(KEY_NAME,
null);
fingerprint_cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (KeyStoreException | CertificateException
| UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Initialisation Failed", e);
}
}

private class FingerprintException extends Exception {
public FingerprintException(Exception e) {
super(e);
}
}

private void generatefingerprintKey() throws FingerprintException {
try {

fingerprint_keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
fingerprint_keyStore = KeyStore.getInstance("AndroidKeyStore");
fingerprint_keyStore.load(null);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
fingerprint_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());
}

fingerprint_keyGenerator.generateKey();

} catch (Exception exc) {
exc.printStackTrace();
throw new FingerprintException(exc);
}
}

}

Add the permissions to the AndroidManifest.xml

Following are the permissions and features required for implementing fingerprint authentication. You just need to add the following code into your manifest file.

<uses-feature android:name="android.hardware.fingerprint"
android:required="true"/>
<uses-permission
android:name="android.permission.USE_FINGERPRINT" />

About the author

Hi guys, i am the author of codesfor. I am a B.Tech graduate currently working as an App developer. Apart from job i am a blogger and a freelancer.

2 Comments

  1. Thirupathi February 16, 2018 Reply
    • rameesAuthor February 16, 2018 Reply

Add a Comment

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