What is fingerprint authentication in Android?…and How to use fingerprint authentication to secure your app? In this tutorial, we will discover how to develop and Android app that user fingerprint authentication to allow or disallow the access to the application by an user.
A fingerprint app uses the smartphone touch sensor to authenticate the user. Android Marshmallow has introduced a set of API that makes easy to use touch sensor to develop an Android fingerprint app. Before Android Marshmallow the method to access to touch sensor was not standard.
There are several benefits of using Android fingerprint authentication:
- Fast and easy to use
- Secure: fingerprint uniquely identifies you
- Online transaction are safer
There are several steps you have to follow before using Android fingerprint authentication and at the beginning, it could seem really complex but this tutorial will guide you step by step to develop a fingerprint app.
Download Android source codeThe final result is an Android fingerprint app that uses fingerprint authentication as shown below:
How to develop an Android fingerprint app that uses fingerprint authentication
As said before, there are several steps to follow to enable fingerprint authentication:
- Verify that the lock screen is secure, or in other words, it is protected by PIN, password or pattern
- Verify that at least one fingerprint is registered on the smartphone
- Get access to Android keystore to store the key used to encrypt/decrypt an object
- Generate an encryption key and the Cipher
- Start the authentication process
- Implement a callback class to handle authentication events
That’s all!!..We will implement these steps.
Before starting, it is important to request the permission to use the touch sensor and the fingerprint authentication. So in the Manifest.xml
, we add:
Now it is time to create our main activity class that handles all the authentication process.
[bctt tweet=”Android fingerprint tutorial #androiddev” username=”survivingwithan”]Verify secure lock screen in Android
The first step is verifying the secure lock screen. This can be done KeyguardManager and FingerprintManager. We get an instance of these two managers using getSystemService:
[java]// Keyguard ManagerKeyguardManager keyguardManager = (KeyguardManager)
getSystemService(KEYGUARD_SERVICE);
// Fingerprint Manager
fingerprintManager = (FingerprintManager)
getSystemService(FINGERPRINT_SERVICE);[/java]
Now, our authentication app can check if all the secure conditions are satisfied:
[java] private boolean checkFinger() {// Keyguard Manager
KeyguardManager keyguardManager = (KeyguardManager)
getSystemService(KEYGUARD_SERVICE);
// Fingerprint Manager
fingerprintManager = (FingerprintManager)
getSystemService(FINGERPRINT_SERVICE);
try {
// Check if the fingerprint sensor is present
if (!fingerprintManager.isHardwareDetected()) {
// Update the UI with a message
message.setText(“Fingerprint authentication not supported”);
return false;
}
if (!fingerprintManager.hasEnrolledFingerprints()) {
message.setText(“No fingerprint configured.”);
return false;
}
if (!keyguardManager.isKeyguardSecure()) {
message.setText(“Secure lock screen not enabled”);
return false;
}
}
catch(SecurityException se) {
se.printStackTrace();
}
return true;
}[/java]
Notice that, the authentication app verifies that, at least, one fingerprint is registered otherwise the authentication process can not start.
The image below shows a message error when the app does not find a fingerprint registered.
If everything is ok and all the conditions are satisfied, the authentication app generates the key and accesses to the Android store.
Access to Android keystore and generate the key
The next step is accessing to the Android keystore and generate the key to encrypt the data. The app does it in a separate method called generateKey().
[java]// Get the reference to the key storekeyStore = KeyStore.getInstance(“AndroidKeyStore”);[/java]
then it is necessary to get the reference to the key generator:
[java]// Key generator to generate the keykeyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
“AndroidKeyStore”);[/java]
and finally, we have to initialize the key generator:
[java]keyGenerator.init( newKeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
keyGenerator.generateKey();[/java]
Notice that we specify the usage of the key: encrypt and decrypt and that the authentication is required to use the key itself. At the end, the app generates the key (last line).
Below, the complete method:
[sociallocker] [java]private void generateKey() throws FingerprintException {try {
// Get the reference to the key store
keyStore = KeyStore.getInstance(“AndroidKeyStore”);
// Key generator to generate the key
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,
“AndroidKeyStore”);
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(KeyStoreException
| NoSuchAlgorithmException
| NoSuchProviderException
| InvalidAlgorithmParameterException
| CertificateException
| IOException exc) {
exc.printStackTrace();
throw new FingerprintException(exc);
}
}[/java]
[/sociallocker]
Create the Android Cipher
Once the key is ready, the last step is creating the Android Cipher that uses the key, we have generated before. The source code is very simple:
[java]private Cipher generateCipher() throws FingerprintException {try {
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + “/”
+ KeyProperties.BLOCK_MODE_CBC + “/”
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
null);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher;
}
catch (NoSuchAlgorithmException
| NoSuchPaddingException
| InvalidKeyException
| UnrecoverableKeyException
| KeyStoreException exc) {
exc.printStackTrace();
throw new FingerprintException(exc);
}
}[/java]
Build the Android fingerprint app using Android Fingerprintmanager
It is time to assemble all these methods and create the Android fingerprint authentication app. This app is very simple and it has a MainClass
that calls the methods shown above and starts the authentication process.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
message = (TextView) findViewById(R.id.fingerStatus);
Button btn = (Button) findViewById(R.id.authBtn);
final FingerprintHandler fph = new FingerprintHandler(message);
if (!checkFinger()) {
btn.setEnabled(false);
}
else {
// We are ready to set up the cipher and the key
try {
generateKey();
Cipher cipher = generateCipher();
cryptoObject =
new FingerprintManager.CryptoObject(cipher);
}
catch(FingerprintException fpe) {
// Handle exception
btn.setEnabled(false);
}
}
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
message.setText(“Swipe your finger”);
fph.doAuth(fingerprintManager, cryptoObject);
}
});
}[/java]
There are a few things to notice. First of all, the Android app creates a CryptoObject
that is used in the authentication process. Moreover, the app shows a button and when the user clicks on it the authentication process starts. The button is disabled if the initial conditions described above are not satisfied. The most important thing to notice is a new class called FingerprintHandler
. This class is a callback class that receives the authentication process events. Moreover, this class starts the authentication process with doAuth method.
Android fingerprint authentication callback
The last step is creating the callback class so that we can receive event notification and we can know when the authentication succeeded or something went wrong. This class extends FingerprintManager.AuthenticationCallback.
[java]public class FingerprintHandlerextends FingerprintManager.AuthenticationCallback {
private TextView tv;
public FingerprintHandler(TextView tv) {
this.tv = tv;
}
@Override
public void onAuthenticationError(int errorCode, CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
tv.setText(“Auth error”);
}
@Override
public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
super.onAuthenticationHelp(helpCode, helpString);
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
tv.setText(“auth ok”);
tv.setTextColor(tv.getContext().getResources().
getColor(android.R.color.holo_green_light));
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
}
public void doAuth(FingerprintManager manager,
FingerprintManager.CryptoObject obj) {
CancellationSignal signal = new CancellationSignal();
try {
manager.authenticate(obj, signal, 0, this, null);
}
catch(SecurityException sce) {}
}
}[/java]
There are some important methods to notice. First of all, the doAuth that starts the authentication process. This method has the CryptoObject, a cancellation signal and the callback listener (this class). The image below shows the app in action:
In this case, the user is authenticated using Android fingerprint authentication.
How to test the fingerprint app in Android 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. Before starting to use the app, you have to configure the fingerprint accessing to the Security menu. When the system asks for fingerprint you have to use the adb command to emulate the finger touch:
[plain]adb -e emu finger touch id(like 1,2, ecc.)[/plain]Finally, when the configuration is done, you get the message shown below:
At the end of this post, hopefully, you gained the knowledge about Android fingerprint api and how to develop an Android fingerprint example app.
how to list my all fingerprints name it’s possible?
Hi Francesco. Thank you for writing this article. I found it very useful!
can you detect input only on the sensor? i want to use it as a button on API 25 and lower
Hello Sir,I liked you posts on Fngerprint t was really usefull . I want to ask that are you using any API to call this?? Please reply ASAP
whether there is a separate fingerprint recognition for a application other than device in-build fingerprint authentication.if any source code(in JAVA) is there please send it to me.
whether there is a separate fingerprint recognition for a application rather than the device in-build.if there, please send the source code(in JAVA).