I would like to use the built-in Fingerprint scanner on Android devices, or most Android devices, to scan the actual fingerprint image or data into my Android app, then send the fingerprint image or data to an API over the internet backed by a database of fingerprints, to see if a given fingerprint (given on any or most Android devices that have fingerprint scanners) matches someone in the database and returns their name (most basic description of my app that focuses on my main question).
Now, I know how to do the API part over the internet with many different programming languages, I'd probably use NodeJS or Elixir for that part, and I know how to do the algorithm to compare a given fingerprint against a database of fingerprints.
The problem I have is that by default and as per guidelines, the Android operating system and Android devices specifically prohibit accessing the internal fingerprint data, and only allow you to authenticate a single or a few users WITHIN a phone and NOT against an outside database with possibly thousands of users and fingerprints or more, and with the given fingerprint to be checked never having been used on a given Android device before, but simply stored in a database or uploaded from a different Android device to that database (served up as an API over the internet).
Also, getting an Android app to communicate with an API with a database backend is trivial. I don't want to address that either, and I don't want any answers to address that.
Specifically, I'm after a hackish way to get at the underlying fingerprint data/scan/image that the hardware produces, or some fingerprint data that is identifiable to an individual, to send to an API database backend over the internet, and let that backend compare the fingerprint data/scan/image sent to it with the database (and I know how to do the comparison part and all that). However, Google guidelines prohibit accessing the underlying fingerprint data in this way that I need for my App.
Solutions
One proposed solution is to issue every user of my app a USB hardware dongle that fingerprint scans, and use the custom API for this hardware. However, my app's use-case scenario involves random people with random Android phones (that already have built-in fingerprint scanning hardware), potentially thousands of people, and they will have little incentive to buy a USB hardware dongle that fingerprint scans, but if I could make it work, they would surely use my app with their built in Android phone fingerprint scanner.
Another proposed solution is to take an actual picture of a person's, for instance, thumb. I don't know if the resolution would be high enough or if this would be practical enough for fingerprint scanning. So my first actual question is (Question #1:) Can a picture taken with most Android phones, in outside conditions, with flash on, be used for fingerprint comparison purposes against a database of maybe 1,000 users? And return the name of the given random user's fingerprint, which is stored in the database, or return that the user was not found in the database based on their fingerprint, using a picture of their thumb? Even if the answer is yes, this is not the ideal solution.
Another proposed solution is to use a picture of a person's face against a database of around 1,000 users with pictures of their faces, instead of using a fingerprint scanner at all. (Question #2a) Would this be accurate (taking a picture of a persons face and doing facial recognition) for 99%+ of cases, in outdoor conditions with the flash turned on? (Question #2b) If so, can you suggest some open-source software for this purpose to be used on the backend, compatible with say NodeJS or Elixir? Or any other programming language too if necessary... and again, this is not the ideal solution.
The ideal solution, if it would work:
Using Code Introspection in Java to interrogate the Android Fingerprint API to determine its hidden objects, methods, functions, variables, etc, and then using Reflection in Java (google it if you don't know what this is) and hack/steal the underlying fingerprint data/image/scan from the phone, then send THAT to the API with the database backend. (Question #3a) This is my primary question and the one I'm most interested in getting a good answer to. Do you know if this is possible, despite the restrictions built into Androids. (Question#3b) If it isn't possible with all Androids, is it possible with some?
(Question #3c) How would I go about this with Code Introspection and Reflection in Java? Which API and parts of the API should I focus on? I'm aware this is hackish and I'm fine with that.
I am aware of the following
As per Nexus FAQs
Your fingerprint data is stored securely and never leaves your Pixel or Nexus phone. Your fingerprint data isn't shared with Google or any apps on your device. Apps are notified only whether your fingerprint was verified.
which explains very well that you can use fingerprints for verification purpose only. Its just an alternative to any app lock available in marketplace.
and also:
FingeprintManager only has these 3 features:
authenticate : for authenticating user
hasEnrolledFingerprints : Determine if there is at least one fingerprint enrolled.
isHardwareDetected : Determine if fingerprint hardware is present and functional.
you can check FingerPrintManager docs here : https://developer.android.com/reference/android/hardware/fingerprint/FingerprintManager.html
And I'm also aware:
"and capture the fingerprint data itself" Not possible, since that data simply isn't available. Google's fingerprint HAL implementation guidelines states that "Raw fingerprint data or derivatives (e.g. templates) must never be accessible from outside the sensor driver or TEE".
However, I have read it suggested that:
you can use android.hardware.fingerprint.Fingerprint.class
/** * Container for fingerprint metadata. * @hide */ public final class Fingerprint implements Parcelable { private CharSequence mName; private int mGroupId; private int mFingerId; private long mDeviceId; // physical device this is associated with ... }
to compare against with enrolled one together with FingerprintManager inner class but visibility of api is hidden and you need use Java Reflection
/** * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject, * CancellationSignal, int, AuthenticationCallback, Handler)}. */ public static class AuthenticationResult { private Fingerprint mFingerprint; ... }
This is suggested as an answer on the post: Fingerprint authetication of multiple users
But further information is needed to verify that this actually works in practice on all Android devices or at least some, and could work in my use case with a database backend.
Summary
I can have the users that are in the database scanned in / fingerprints registered, the first time with any method, I just need to know how to use an standard Android phone without a custom 3rd party USB fingerprint scanning dongle to scan fingerprints and send them to this database (and I already know how to send them to the database and compare them, I just don't know exactly how to get them from the Android device so I want to try a hackish-method of Code Introspection and Reflection.)