Authentication using fingerprint in your Android application

Sep 18 2018Written by Manektech Team

Are you using latest version of android? Yes, Then use Android’s latest feature Fingerprint authentication. Only your have authorisation to access your own phone and app. After release of Android 6.0 Marshmallow android has released fingerprint secured authentication, Which allow you to secure your app and phone. It’s also called as biometric authentication.

It’s very Fast and Dependable way of authenticating user’s identity
- Nowadays all the payment apps are using fingerprint access to allow you send payment and receive payment.
- It’s very secured so it can not allow any other person’s fingerprint identity to access your phone and payment app.
- To implement this functionality in your app if you do not have Marshmallow version 6.0 than you have to download from Android SDK.
- It will not accessible in non-fingerprint support smartphone.

Steps to enable fingerprint in your smartphone.

- Your device should have fingerprint scanner which can authenticate your thumb or finger.
- Device should be compatible with android Marshmallow version 6.0.
- You have to set your device lock screen as password, pin or pattern and you have to add at least single fingerprint.

Steps for implementation via programming.
Create new Project in Android Studio
1. Create a new project in Android Studio from File ⇒ New Project and set the minimum SDK version to Android 6.0 (API 23).
2. Without permission it won’t allow you to start your app so first of all you have to add permission in AndroidManifest.xml file.

- App also need to add permission to add feature of touch sensor in order to access finger touch.

- App will check that your device has registered fingerprint or not if not then it will give message that please add at least one fingerprint in your smartphone.
XML coding for frontend UI.
activity_main.xml

xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_fingerprint"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#252b30"
android:orientation="vertical">

<ImageView
android:id="@+id/icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginBottom="30dp"
android:layout_marginTop="100dp"
android:paddingTop="2dp"
android:src="@drawable/ic_action_fingerprint" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="10dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
android:text="@string/title_fingerprint"
android:textColor="@android:color/white"
android:textSize="20sp" />

<TextView
android:id="@+id/desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:gravity="center"
android:paddingEnd="30dp"
android:paddingStart="30dp"
android:text="@string/desc_fingerprint"
android:textAlignment="center"
android:textColor="@android:color/white"
android:textSize="16sp" />

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


Create fingerprint authentication part.

You have to check that your device has software,hardware settings to access fingerprint authentication.

Initialize both Android KeyguardManager and FingerprintManager.

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

If your device support both this conditions than you are now accessible to use fingerprint authentication.

To perform this authentication we have to create key,cipher and cryptoobject.

Below code will give you access to gain keystore instance which allows you to store cryptographic keys.

- Initialize empty keystore
- Initialize keyGenerator
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);
}

 

cryptoObject = new FingerprintManager.CryptoObject(cipher);
Helper helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);

Create FingerPrintHandler class to access FingerprintManager Authentication
- onAuthenticationFailed() it will called when your authentication is incorrect or not match.
- onAuthenticationError(int errMsgId, CharSequence errString) it will called if there is any kind of fatal error.
- onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) it will called when your fingerprint is correct or successfully authorized.
- onAuthenticationHelp(int helpMsgId, CharSequence helpString) This method can give additional information regarding fingerprint authentication.

FingerprintHandler.java file
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {

private Context context;
// Constructor
public FingerprintHandler(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);
((Activity) context).finish();
Intent intent = new Intent(context, HomeActivity.class);
context.startActivity(intent);
}

public void update(String e, Boolean success){
TextView textView = ((Activity)context).findViewById(R.id.errorText);
textView.setText(e);
ImageView icon = ((Activity)context).findViewById(R.id.icon);
if(success){
icon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_action_fingerprint_success));
textView.setTextColor(ContextCompat.getColor(context,R.color.colorAccess));
}else {
icon.setImageDrawable(ContextCompat.getDrawable(context,R.drawable.ic_action_fingerprint_error));
textView.setTextColor(ContextCompat.getColor(context,R.color.colorError));
}
}
}


MainActivity.java file
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 = "androidHive";
private Cipher cipher;
private TextView textView;
private ImageView icon;

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

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

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

// 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,
* you can redirect the user to a default authentication activity from here.
* Example:
* Intent intent = new Intent(this, DefaultAuthenticationActivity.class);
* startActivity(intent);
*/
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);
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("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);
}
}
}

How to run app in your device and emulator
- To test the app, it is possible to use a real device that has a touch sensor. Anyway, it is possible to test the app in the emulator too.
- To use this app in Android emulator you have to configure it
- Your device should be compatible of Marshmallow 6.0 version.
- If your device do not have registered of fingerprint it will show you message as per first screen
- If your fingerprint does not match it will show your incorrect fingerprint message

Contact us

Here to Help ambitious people TRANSFORM the Digital Solutions!