On Github Mauin / gdgfingerprint
A crash course in fingerprint authentication
Marvin Ramin
You are the 0.7%!
Congrationations: You are part of the <0.7 %
... and hopefully some nice UI
targetSdkVersion 23
USE_FINGERPRINT permission
Device or emulator with fingerprint sensor
return FingerprintManagerCompat.from(context);
Just build it!
No standard UI exists
Typically a dialog
Must not be a dialogUse this icon in your UI
"You must implement the user interface for the fingerprint authentication flow on your app, and use the standard Android fingerprint icon in your UI." d.android.com Though you can tint the icon backgroundLet the user chose to set up fingerprint
Always provide a fallback
Show the user success and error states!
Setup during purchase flow, maybe app start to lock the app Once setup, let the user go back to password!now you're encrypting with fingerprints
...replaces some sort of other authentication
You wouldn't just add fingerprint authentication for the sake of it. User should be present Maybe you still need your old form of authentication for network calls Think password, token, pin, something else Where do you store it?return Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7
);
4 easy steps we will go through
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, PURPOSE_ENCRYPT | PURPOSE_DECRYPT)
.setBlockModes(BLOCK_MODE_CBC)
.setEncryptionPaddings(ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.build());
return keyGenerator.generateKey();
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
keyGenerator.init(new KeyGenParameterSpec.Builder(keyName, PURPOSE_ENCRYPT | PURPOSE_DECRYPT)
.setBlockModes(BLOCK_MODE_CBC)
.setEncryptionPaddings(ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(true)
.build());
return keyGenerator.generateKey();
Or load your Key from the KeyStore
Userauthentication required! Means lock screen authentication Fingerprint required to use this key Don't just create a new key every time or for decryptioncipher.init(Cipher.ENCRYPT_MODE, key);Encrypt mode with the key we just found
cipher.init(Cipher.ENCRYPT_MODE, key);Encrypt mode with the key we just found
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));Decrypt mode and store the Initialization Vector somewhere You can retrieve this after the encryption from the Cipher
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));Decrypt mode and store the Initialization Vector somewhere You can retrieve this after the encryption from the Cipher
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));IV can be stored somewhere. Do not reuse IV's!
CryptoObject cryptoObject = new FingerprintManagerCompat.CryptoObject(cipher);
fingerprintManager.authenticate(cryptoObject, 0, cancellationSignal, callback, null);Pass this into the .authenticate() call Nothing is encrypted yet! And hope for the succeeded callback!
CryptoObject cryptoObject = new FingerprintManagerCompat.CryptoObject(cipher);
fingerprintManager.authenticate(cryptoObject, 0, cancellationSignal, callback, null);Pass this into the .authenticate() call Nothing is encrypted yet! And hope for the succeeded callback!
Access to the CryptoObject
Cipher cipher = authenticationResult.getCryptoObject().getCipher();
byte[] encryptedBytes = cipher.doFinal("1234".getBytes("UTF-8"));
Cipher cipher = authenticationResult.getCryptoObject().getCipher();byte[] encryptedBytes = cipher.doFinal("1234".getBytes("UTF-8"));
get access to the cipher
Cipher cipher = authenticationResult.getCryptoObject().getCipher();
byte[] encryptedBytes = cipher.doFinal("1234".getBytes("UTF-8"));
Encrypt with the doFinal method
Result is encrypted byte array
KeyPermanentlyInvalidatedException
All your encryption keys are invalidated
Makes sense, but is annoying Protects your encrypted data