Created
February 19, 2020 18:05
-
-
Save isaidamier/b88d10b36e5be3489cea837e9372711c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MainActivity : AppCompatActivity() { | |
private lateinit var textInputView: AppCompatEditText | |
private lateinit var textOutputView: AppCompatTextView | |
private lateinit var biometricPrompt: BiometricPrompt | |
private lateinit var promptInfo: BiometricPrompt.PromptInfo | |
private var readyToEncrypt: Boolean = false | |
private lateinit var cryptographyManager: CryptographyManager | |
private lateinit var secretKeyName: String | |
private lateinit var ciphertext:ByteArray | |
private lateinit var initializationVector: ByteArray | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
cryptographyManager = CryptographyManager() | |
// e.g. secretKeyName = "biometric_sample_encryption_key" | |
secretKeyName = getString(R.string.secret_key_name) | |
biometricPrompt = createBiometricPrompt() | |
promptInfo = createPromptInfo() | |
textInputView = findViewById(R.id.input_view) | |
textOutputView = findViewById(R.id.output_view) | |
findViewById<Button>(R.id.encrypt_button).setOnClickListener { authenticateToEncrypt() } | |
findViewById<Button>(R.id.decrypt_button).setOnClickListener { authenticateToDecrypt() } | |
} | |
private fun createBiometricPrompt(): BiometricPrompt { | |
val executor = ContextCompat.getMainExecutor(this) | |
val callback = object : BiometricPrompt.AuthenticationCallback() { | |
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { | |
super.onAuthenticationError(errorCode, errString) | |
Log.d(TAG, "$errorCode :: $errString") | |
} | |
override fun onAuthenticationFailed() { | |
super.onAuthenticationFailed() | |
Log.d(TAG, "Authentication failed for an unknown reason") | |
} | |
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { | |
super.onAuthenticationSucceeded(result) | |
Log.d(TAG, "Authentication was successful") | |
processData(result.cryptoObject) | |
} | |
} | |
//The API requires the client/Activity context for displaying the prompt view | |
val biometricPrompt = BiometricPrompt(this, executor, callback) | |
return biometricPrompt | |
} | |
private fun createPromptInfo(): BiometricPrompt.PromptInfo { | |
val promptInfo = BiometricPrompt.PromptInfo.Builder() | |
.setTitle(getString(R.string.prompt_info_title)) // e.g. "Sign in" | |
.setSubtitle(getString(R.string.prompt_info_subtitle)) // e.g. "Biometric for My App" | |
.setDescription(getString(R.string.prompt_info_description)) // e.g. "Confirm biometric to continue" | |
.setConfirmationRequired(false) | |
.setNegativeButtonText(getString(R.string.prompt_info_use_app_password)) // e.g. "Use Account Password" | |
// .setDeviceCredentialAllowed(true) // Allow PIN/pattern/password authentication. | |
// Also note that setDeviceCredentialAllowed and setNegativeButtonText are | |
// incompatible so that if you uncomment one you must comment out the other | |
.build() | |
return promptInfo | |
} | |
private fun authenticateToEncrypt() { | |
readyToEncrypt = true | |
if (BiometricManager.from(applicationContext).canAuthenticate() == BiometricManager | |
.BIOMETRIC_SUCCESS) { | |
val cipher = cryptographyManager.getInitializedCipherForEncryption(secretKeyName) | |
biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher)) | |
} | |
} | |
private fun authenticateToDecrypt() { | |
readyToEncrypt = false | |
if (BiometricManager.from(applicationContext).canAuthenticate() == BiometricManager | |
.BIOMETRIC_SUCCESS) { | |
val cipher = cryptographyManager.getInitializedCipherForDecryption(secretKeyName,initializationVector) | |
biometricPrompt.authenticate(promptInfo, BiometricPrompt.CryptoObject(cipher)) | |
} | |
} | |
private fun processData(cryptoObject: BiometricPrompt.CryptoObject?) { | |
val data = if (readyToEncrypt) { | |
val text = textInputView.text.toString() | |
val encryptedData = cryptographyManager.encryptData(text, cryptoObject?.cipher!!) | |
ciphertext = encryptedData.ciphertext | |
initializationVector = encryptedData.initializationVector | |
String(ciphertext, Charset.forName("UTF-8")) | |
} else { | |
cryptographyManager.decryptData(ciphertext, cryptoObject?.cipher!!) | |
} | |
textOutputView.text = data | |
} | |
companion object { | |
private const val TAG = "MainActivity" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment