Automating Biometric Authentication in Android

Jul 10, 2019 1:10:51 PM

 

Biometric authentication technology might only be a few years old, but was actually envisioned as early as the 1980's! (Remember the movie Back to the Future II?) Today, we frequently rely on a biological scan of some description (fingerprint, iris, face, or body) to unlock our electronic devices, leaving us frustrated when the scan doesn't work and we have to log-in manually.

To provide a more technical definition, biometrics are measurements of the human body that are used as metrics or keys in the process of authenticating, identifying, or controlling electronic devices.

Here's how the authentication process works in Android

The biometrics process begins with either a full-view activity or dialog component in the UI, both of which are usually triggered by some kind of user interaction like tapping a button or switching tasks. At this point, the device runs a fingerprint manager that implicitly communicates with the fingerprint service running in the background. Then, the service attempts to communicate with the fingerprint scanner hardware and pulls for the user's fingerprint.

Once the scanner registers a good impression of the fingerprint, it will validate the fingerprint with the one stored in the device's Trust Zone, an isolated component (that stores sensitive biometric data) that can never be accessed directly from Android. Once the fingerprint is validated successfully, the UI forwards to the next activity, signing the user in.

The issue with automating biometric tests in Android is that it's impossible to 1) sidestep the biometric prompt in the test flow without a physical intervention, and 2) programmatically intervene with the Trust Zone.

So, we created our very own Android biometrics SDK

Here at HeadSpin, we empower app developers to launch higher quality software, faster. So, we opted for a developer-first solution and created our own Android biometrics SDK, compatible with Android API Level 23 and later.

Scroll down for a step-by-step guide on installing HeadSpin's Android biometrics SDK

The webinar (and transcript) that follow provides a detailed explanation of Android's biometric authentication process, as well as a step-by-step guide on installing HeadSpin's Android biometrics SDK.

As always, reach out to us at headspin.io/contact with any questions, and we'd be happy to help!

Testing Biometrics on Android-Joe

 

Webinar Transcript

Hi everyone. Welcome to HeadSpin Webinar. I'm Joe Chasinga, a Software Engineer at HeadSpin. I work on device instrumentation and also the biometrics SDK for both the iOS and Android platforms. 

Today, we're going to be talking about the Android biometrics SDK and how to use the library package to effectively run your biometrics test. 

Let’s start with talking about what really are biometrics. Biometrics are the use of users’ body measurements and calculations, like metrics or keys, as authentication, identification, or control methods. The most common forms today are fingerprint scanning -  that's really popular face recognition, iris scanning, and skeleton detection, as you might have seen with the Xbox Kinect sensors. 

Here’s a little reference from quite a popular film - Back To The Future 2 - from back in 1989, 30 years ago. In the movie, it envisions that in 2015, we would be using fingerprint [scanning] to access or to unlock doors, instead of door knobs or locks, and even use [fingerprint scanning] to pay for taxis, or Uber, for that matters. Now, we’ve been lagging behind just a little bit, but we're getting there.

Here comes the issues with automating biometric tests on Android. The obvious problem here is that it's quite impossible to interact with or sidestep the biometric prompt in the test flow without a physical intervention, because it's not true, or even possible to programmatically intervene with the secure processor that stores the raw fingerprint data or the fingerprint scanner hardware. So, that's really a problem, right? That's really obvious. 

There is a huge gig economy around clicking mobile devices - they're called click farms and they are all over the world in many parts of the world. However, I don't think it's a good idea to have a gig worker run a fingerprint on the apps that we want to test. 

So, let's dive into a very high level flow of biometrics process in Android here. It usually start with either a full-view activity or a dialogue component in the UI, usually triggered by some kind of user interaction, like tapping on a button or changing to a new activity. And then, it runs the fingerprint manager that implicitly talks to the fingerprint service that runs in the background. And then, the service will communicate with the fingerprint scanner hardware. Let's see how that works out. 

Here, I can see that programmatically, when the UI is loaded, it’s going to instantiate the fingerprint manager, or it’s going to ask for the readiness of the fingerprint manager. Afterward, when we call a “Authenticate” method on this instance of fingerprint manager and pass along relevant parameters like the crypto object and call back object, it will implicitly talk to the fingerprint service. And then the service will ask the fingerprint scanner to warm itself up. What that means is the scanner will start running and pulling for the user’s fingerprint.

And once there's the fingerprint here, as you can see here, a nice, dark fingerprint impression is captured properly by the scanner. Just so you know, there's a few conditions when the fingerprint impression might not be registering properly. Like for instance, the scanner is dirty or the angle of the impression is not really optimal. 

But, that being said, when the sensor gets a pretty good impression of a fingerprint, it will validate the fingerprint with the one that's stored in another part of Android called the Trust Zone, which is an isolated hardware with its own operating system and it can never be accessed directly from Android. Once everything is validated, it's going to return “Result” to the service and then the service will tell the fingerprint manager to run the relevant callback based on the result and pass back here.

Either it's “onSucceeded,” “onFailed” or “onError.” In the case of onSucceeded, the action is likely to dismiss the UI prompt or dialog, and then maybe fetch the user's data from the database or the device cache, and then populate the next activity with the data, and then move the user to the next activity, creating a sense of the user of being signed in.

With onFailed or onError, a good fallback or a good default would be to show a prompt or maybe a toast that tells the user about the error or the failure, and always make sure to provide good feedback and graceful fallback in the case of failure or errors, so that the user knows where to go to just enter the username, email, or password.

Here's a little video demo of myself: I'm testing out an app here called “healthtest” - it doesn't do much, but just enough. Whenever we tap the log-in button, it’s going to display a dialog asking for the fingerprint. And once it can validate a fingerprint, it’ll just dismiss the dialog. Let's see what happens here. [Pause.] 

So at this point, I am tapping the log-in button, and then I am going to use my finger to log in, and that's it. There's some audio there. [Repeat of video.] It’s a very simple flow, but it's a flow that’s normally not easy to automate.

Here's another video demo of the same app, but this time it’s using our HeadSpin fingerprint SDK or biometrics SDK. There's no fingerprint involved here. All I'm doing is sending a post request - as you can see here, it looks like a token, but it's the post request for the payload here, and that's the prompt. And then again, that’s your 200 status code - success, true. And then, it just dismissed the prompt.

Before we go on and talk about how to install this awesome library, be reminded that this only works with Android API level 23 and later. This is not specific to the library - just the versions or the ones that support the fingerprint feature. And then secondly, the test device should have a valid fingerprint on the role - the SDK is not doing anything magical, so the target device needs to be able to authenticate with your fingerprint. And last but not least, this goes without saying, do not distribute your test build in the wild. You run the risk of somebody hijacking your users biometrics by using external connection. So please, we recommend only using our test build with our highly secure devices. 

Installing HeadSpin's Android biometrics SDK

So without further ado, let's head over to headspin.io Settings page. If you are already a HeadSpin costumer, you should be able to get access to the download link and the documentation link, which talks in more detail about what we are discussing right now.

Then, head over to your Android studio editor. Hopefully, this is how your Android studio environment looks for most of you guys. First of all, create a directory called “source/main/libs” under your apps directory. This is pretty optional - if you already know what you’re doing, you don't have to do it - just make sure you have a nice safe directory for the library. 

And then, you download it: instruments-release.arr file to the newly-created “libs” directory. Again, it can be right in the directory. In your app module “build.gradle” - the line “implementation(name: ‘instruments-release’ , ext: ‘aar’) under dependencies block. And last but not least, sometimes, your environment might not be able to find the library. In that case, add this “flatDir” and then provide it with your libraries directory under the “Repositories” block, and you should be good to go.

Okay. So now let's walk through some code. This is the code for the fingerprint dialog segment. It's the code for the UI that you’ve already seen on the test app that’s part of the biometrics. These are all pretty standard - really up to how you write your code. 

Please notice the two lines here. For your test build, to integrate our biometrics SDK:

Import io.headspin.instruments.HSFingerprintManager

So io.headspin.instruments is the package name. 

It's helpful to also import HSFingerprintAuthCallback, which is a helpful wrapper around the original authentication callback that provides useful defaults for all the cases that you may get from the authentication process.

Now, let's go through this class. You'll notice here I actually define the HSFingerprintManager variable here early within the class. And I also define my custom callback here that inherits the HSFingerprintAuthCallback that I imported from the library. So, as you can see, I only care about customizing the “onAuthenticationSucceeded” case. So, I only override this method here, and what I wanted to do is to just dismiss the dialog, which is exactly what I’m doing here, and I don't really care about onFailed or onError. 

The HSFingerprintAuthCallback provides defaults - it will display a toast with some helpful message of the failure or the error, but of course you can still override those. 

Okay. Let's move on. In the onAttach method here, this gets run when the view is loaded, or the dialog in this case is loaded. This is where you usually want to instantiate your HSFingerprintManager instance and assign it to your HSFingerprintManager variable.

If you’re using an activity instead of a dialog, the method is probably going to be onCreate or something else, but the concept here is the same. You want to instantiate HSFingerprintManager here when the view gets loaded. 

Moving on here, onDetach is equivalent to the onDestroy method. Before we clean up, we’ll want to view HSFingerprintManager with the close method. What this does is it cleans up any TCP connections in the background that are communicating with the external or, in this case, the HeadSpin platform http server. 

This is the onCreate dialog method. We’d assign our custom callback to a helper. And then, this is where we create cryptoObject. 

And then, this is a very important part. We call authenticateMethod on HSFingerprintManager, then passed the cryptoObject, and then the handler or the Callback as parameters.

Remember, this is the part when it starts to warm up the fingerprint scanner. So, when you call this, it's going to load the scanner and the scanner will start to pull for the fingerprint from the user. 

This is where you actually set some useful messages and [do] some button styling. The majority of the code will be about creating a relevant key in order to create the secure cryptoObject. We won't get into that, but please make sure you don't copy these algorithms here because they are not recommended for production. 

These are all about generating keys, very standard. Something to note here: you might want to check for permission first and [whether] your device has permission to use fingerprint at all. Otherwise, there's no use in authenticating. You should just provide a meaningful toast with a message to the user. 

This is how you actually test hasEnrolledFingerprints on your device. If [it’s not on the device], you’re better [off] just flashing a toast or a message: something like, “Register at least one fingerprint in the settings.”

If there's anything else that is unclear to you and you want to get more information, please feel free to consult are awesome documentation. This concludes our webinar for today. We have a couple extra minutes for a Q&A session, so I’m going to check for some questions here. By the way, now is the time, if you're interested, you can get in touch with us. Head over to headspin.io/contact, include this promo code [ROCKSPIN] in your message to get your free trial. 

Webinar Q&A  

Q: Does this library work with Java project?

A: Yes, it does. Kotlin and Java are very interchangeable - they are very compatible - so, you could use this aar library without change to your code.

Q: How can we download the library?

A: If you're already an existing customer, you should have access to the SDK. If you’re not, or if you don’t have access, please get in touch with us and we’d be happy to help. 

Q: Is this library secure?

A: Programmer-wise, it is, because it's just a wrapper around the original fingerprint manager, which means that when you call the Authenticate method, the wrapper just passes along the cryptoObject and the callback to the fingerprint authentication process. However, the wrapper itself actually creates a TCP connection to the outside world, so it’s highly recommended that you do not use your test build in public and only trust HeadSpin and use it on one of our devices. The SDK will work out of the box with our platform, our infrastructure, and the API endpoints. 

With that, thank you everyone for joining today, and for all the great questions. Please stay tuned for more HeadSpin webinars coming up in the next few weeks!