of P Preview (as at the time of submission of this talk) • Provide consistent and easy API for developers • Provide consistent system UI that is sensor-agnostic
key for encryption and decryption Asymmetric: aka “public key” - different keys for encryption and decryption https://www.cs.utexas.edu/users/byoung/cs361/lecture44.pdf
getSystemService(KeyguardManager::class.java) // Show error - can't proceed without sensor if (!fingerprintManager.isHardwareDetected) {...} // Show error - can't proceed without fingerprint if (!fingerprintManager.hasEnrolledFingerprints()) {...}
getSystemService(KeyguardManager::class.java) // Show error - can't proceed without sensor if (!fingerprintManager.isHardwareDetected) {...} // Show error - can't proceed without fingerprint if (!fingerprintManager.hasEnrolledFingerprints()) {...}
getSystemService(KeyguardManager::class.java) // Show error - can't proceed without sensor if (!fingerprintManager.isHardwareDetected) {...} // Show error - can't proceed without fingerprint if (!fingerprintManager.hasEnrolledFingerprints()) {...} // Proceed with auth
getSystemService(KeyguardManager::class.java) // Show error - can't proceed without sensor if (!fingerprintManager.isHardwareDetected) {...} // Show error - can't proceed without fingerprint if (!fingerprintManager.hasEnrolledFingerprints()) {...} // Proceed with auth Deprecated
getSystemService(KeyguardManager::class.java) // Show error - can't proceed without sensor if (!fingerprintManager.isHardwareDetected) {...} // Show error - can't proceed without fingerprint if (!fingerprintManager.hasEnrolledFingerprints()) {...} // Proceed with auth New API offers callbacks to handle errors and unsatisfied criteria
{ keyStore = KeyStore.getInstance("AndroidKeyStore") } catch (e: KeyStoreException) { throw RuntimeException("Failed to get an instance of KeyStore", e) } 2. Create & initialize a cipher
key // Create Keystore try { keyStore = KeyStore.getInstance("AndroidKeyStore") } catch (e: KeyStoreException) { throw RuntimeException("Failed to get an instance of KeyStore", e) } // Create KeyGenerator (this will be used to create the key) try { keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM_AES, "AndroidKeyStore") } catch (e: Exception) { when (e) { is NoSuchAlgorithmException, is NoSuchProviderException -> throw RuntimeException(...) else -> throw e } 2. Create & initialize a cipher
= KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT val builder = KeyGenParameterSpec.Builder(“default_key”, keyProperties) .setBlockModes(BLOCK_MODE_CBC) .setUserAuthenticationRequired(true) .setEncryptionPaddings(ENCRYPTION_PADDING_PKCS7) .setInvalidatedByBiometricEnrollment(true) // generate keys keyGenerator.init(builder.build()) keyGenerator.generateKey() } catch (e: Exception) { // handle exceptions } Key is authorized to be used only when user has been authenticated (e.g unlocked phone)
Cipher try { val cipherString = "$KEY_ALGORITHM_AES/$BLOCK_MODE_CBC/$ENCRYPTION_PADDING_PKCS7" cipher = Cipher.getInstance(cipherString) } catch (e: Exception) { when (e) { is NoSuchAlgorithmException, is NoSuchPaddingException -> throw RuntimeException("Failed to get an instance of Cipher", e) else -> throw e } }
keyStore.load(null) val secretKey = keyStore.getKey("default_key", null) as SecretKey // init cipher.init(Cipher.ENCRYPT_MODE, secretKey) return true } catch (e: Exception) { when (e) { is KeyPermanentlyInvalidatedException -> return false ... else -> throw e } } } Unrecoverably invalidated due to - change in security settings of the phone, or since we configured setInvalidatedByBiometricEnrollment to enrollment of new fingerprint
Warm up the sensor and start listening for authentication val manager = getSystemService(FingerprintManager::class.java) manager.authenticate(cryptoObject, cancellationSignal, 0, callback, null); 3. Listen for fingerprint auth events Authenticating with the old FingerprintManager
Warm up the sensor and start listening for authentication val manager = getSystemService(FingerprintManager::class.java) manager.authenticate(cryptoObject, cancellationSignal, 0, callback, null); 3. Listen for fingerprint auth events Authenticating with the old FingerprintManager Deprecated
fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { // handle error } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { // handle result } override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence?) { // handle help message if necessary } override fun onAuthenticationFailed() { // fingerprint recognized but doesn't match } }
fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { // handle error } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { // handle result } override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence?) { // handle help message if necessary } override fun onAuthenticationFailed() { // fingerprint recognized but doesn't match } }
fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { // handle error } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { // handle result } override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence?) { // handle help message if necessary } override fun onAuthenticationFailed() { // fingerprint recognized but doesn't match } }
fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { // handle error } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { // handle result } override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence?) { // handle help message if necessary } override fun onAuthenticationFailed() { // fingerprint recognized but doesn't match } }
fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { // handle error } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { // handle result } override fun onAuthenticationHelp(helpCode: Int, helpString: CharSequence?) { // handle help message if necessary } override fun onAuthenticationFailed() { // fingerprint recognized but doesn't match } }
and other ways) • Subtle enrollment - there should be a place in your settings where users can enroll to use fingerprint authentication in your app • Provide as much info as possible to your users to help them
and other ways) • Subtle enrollment - there should be a place in your settings where users can enroll to use fingerprint authentication in your app • Provide as much info as possible to your users to help them • Ensure good API practices with signed requests
and other ways) • Subtle enrollment - there should be a place in your settings where users can enroll to use fingerprint authentication in your app • Provide as much info as possible to your users to help them • Ensure good API practices with signed requests • The APIs may not be final yet
and other ways) • Subtle enrollment - there should be a place in your settings where users can enroll to use fingerprint authentication in your app • Provide as much info as possible to your users to help them • Ensure good API practices with signed requests • The APIs may not be final yet • No Compat APIs yet