7

I'm want to encrypt and decrypt files from SD-card using AES. In order to do it we always need a seed (usually a string which is inserted by user as a password):

public static byte[] generateKey(String password) throws Exception{
   byte[] keyStart = password.getBytes("UTF-8");
   KeyGenerator kgen = KeyGenerator.getInstance("AES");
   SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
   sr.setSeed(keyStart);
   kgen.init(128, sr);
   SecretKey skey = kgen.generateKey();
   return skey.getEncoded();
}

I want to skip this step (inserting password by user) and JUST require user to Authenticate by finger-print sensor and then start Encryption process!

I wonder if there is a way that I can Obtain a unique-key for each different finger that touches finger-print sensor that can be used as SEED to create SecretKey!?

I read some questions on SO and related samples on github but I still cannot find a way to do it.

to clear the problem: I've done implementing the AES itself and completely OK with it and I just need to find a way to get unique-key from finger-print sensor after Authentication.

CL.
  • 173,858
  • 17
  • 217
  • 259
Jalal Aghazadeh
  • 164
  • 4
  • 18
  • 1
    A fingerprint cannot be directly used as a key in the same way as a password, because fingerprints vary slightly from reading to reading. Worse yet, fingerprints are not secret -- you leave them all over the place. – President James K. Polk Jun 13 '17 at 16:37
  • @JamesKPolk: my assumption about how finger-print sensor detects the owner of the device is that finger-print sensor generates a hash-key based on each finger that touches finger-print sensor. Then finger-print sensor compares generated hash-key with hash-key that is generated from owner's finger-print which is kept secret in somewhere (when owner was about to activate this authentication on device). If such thing exists, I need to find it and use it as password (since we don't know how finger-print sensor generates hash-key, this could be a reliable password) – Jalal Aghazadeh Jun 14 '17 at 06:17
  • 2
    @JalalAghazadeh Not related to your question, but you should not be using `SHA1PRNG` in any code. It is deprecated – Shahid Thaika Aug 14 '17 at 08:06
  • @JalalAghazadeh did you succeed? I'm seeking for the exact same thing and can't find answer... – ben May 21 '18 at 18:03
  • @ben not really :( because as "James K Polk" mentioned finger print is not secret an you left it everywhere and there was no global API to get such thing from finger-print-chip and every company has his own story. some let you access to such Key via some custom-api and some don't! – Jalal Aghazadeh May 22 '18 at 00:33

1 Answers1

16

Updated 2019-10-14

TL;DR

No, you can't access the fingerprint. You can only get a "thumbs up" or "thumbs down" from the Biometric API. This is intentional by design.

You can, however, leverage the Android Keystore for hardware-backed cryptographic operations, and require user re-authentication to release the key. This pretty much does what you want.

The long answer

Generating a password-like seed from a fingerprint is impossible. As James K Polk commented, fingerprints vary when scanned, and they are never legibly stored directly on the device.

When a fingerprint is being enrolled, its image is temporarily stored on secure device memory, where it is processed to generate validation data and a fingerprint template (these are all inaccessible to the Android OS). The raw image is then discarded. When a finger is scanned, the image is compared to the validation data generated before, and if it matches to a certain degree of certainty, a user is deemed as authenticated.

Biometric operations are conducted inside of Android's Trusted Execution Environment (TEE). This is a completely isolated OS running either on a protected part of the CPU on a separate coprocessor on modern devices (SE).

It's a virtually untouchable environment with a restricted interface and hardware barriers put in place to protect against tampering with the chip and forced extraction of biometric validation data and cryptographic keys.

Solution

Going back to your original question, no, you can't get any unique finger identification. This would be inherently insecure, as any application could read the secret!

What you can do, is leverage Android's hardware-backed Keystore and require device-level authentication to release hardware-backed cryptographic keys (setUserAuthenticationRequired(true)). This means generating a random secret which is securely saved to the Keystore, requiring a finger swipe to release the key to userspace. I can't stress the word hardware-backed enough.

You have no control over which finger is can be used and whether vendor-specific implementations allow bypassing of biometrics with the device unlock pattern, for example.

Android Keystore

The Keystore's purpose is to protect cryptographic keys. Keys can only be retrieved by the application that owns them once sufficient requirements have been met, such as recent or immediate biometric authentication.

Keys can be protected against malicious extraction, and on modern devices, hardware bound, meaning they never leave the secure hardware (TEE/SE), and therefore are never exposed to your Android application. Any cryptographic operations, such as AES encryption/decryption, are securely executed outside of userspace (on secure hardware), and enrolling new fingerprints/changing the lock pattern will permanently invalidate the key. In this mode of operation, the Keystore entry merely serves as an "interface" to conduct crypto operations inside of the secure hardware, the true secret is never exposed to your application.

In summary

There is a Fingerprint/Biometric API, which is there purely for convenience, allowing you to quickly confirm an action by requiring the user to authenticate. It boils down to a "yes"/"no" answer from the TEE/SE, and vary greatly depending on the phone manufacturer!

The Keystore is a hardware-backed vault for cryptographic keys. Devices running API-level 28+ also have access to Strongbox Keymaster, if the device hardware supports it, which restricts cryptographic operations to a dedicated security CPU with more secure storage.

These features are device/vendor specific! And could be compromised/insecure! Warn users before enabling fingerprint authentication if you aren't sure about the device. The only truly secure encryption method is prompting the user every time for the decrypt key (in this case, the mind is the hardware-backed store). Having it stored anywhere, even in live memory, is always a calculated risk.

Doing cryptography right is extremely difficult. I highly advise that you research and try to understand the basics, and what additional security Android has to offer, before attempting to use this in production.

Marcus Cemes
  • 692
  • 1
  • 8
  • 18