2021年5月2日星期日

how to use lock screen password instead of fingerprint

I'm using the ANDROID BIOMETRIC LIBRARY for authentication and encryption. Right now it uses the fingerprint but I want it to use the default lock screen password/pin when fingerprint isn't enabled.

object BiometricPromptUtils {      private const val TAG = "BiometricPromptUtils"      fun createBiometricPrompt(          activity: AppCompatActivity,          processCancel: () -> Unit,          processSuccess: (BiometricPrompt.CryptoObject?) -> Unit      ): BiometricPrompt {          val executor = ContextCompat.getMainExecutor(activity)            val callback = object : BiometricPrompt.AuthenticationCallback() {                override fun onAuthenticationError(errCode: Int, errString: CharSequence) {                  super.onAuthenticationError(errCode, errString)                  Log.d(TAG, "errCode is $errCode and errString is: $errString")                  if (                      (errCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON)                      or (errCode == BiometricPrompt.ERROR_USER_CANCELED)                  ) {                      processCancel()                  }              }                override fun onAuthenticationFailed() {                  super.onAuthenticationFailed()                  Log.d(TAG, "Biometric authentication failed for unknown reason.")              }                override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {                  super.onAuthenticationSucceeded(result)                  Log.d(TAG, "Authentication was successful")                  processSuccess(result.cryptoObject)              }          }          return BiometricPrompt(activity, executor, callback)      }        fun createPromptInfo(activity: AppCompatActivity): BiometricPrompt.PromptInfo {          return BiometricPrompt.PromptInfo.Builder().apply {              setTitle(activity.getString(R.string.prompt_info_title))              setConfirmationRequired(false)              setNegativeButtonText(activity.getString(R.string.prompt_info_cancel_text))          }.build()      }  }  interface CryptographyManager {        fun getInitializedCipherForEncryption(keyName: String): Cipher        fun getInitializedCipherForDecryption(keyName: String, initializationVector: ByteArray): Cipher        fun encryptData(plaintext: String, cipher: Cipher): EncryptedData        fun decryptData(ciphertext: ByteArray, cipher: Cipher): String        fun saveEncryptedDataToSharedPrefs(          encryptedData: EncryptedData,          context: Context,          filename: String,          mode: Int,          prefKey: String      )        fun getEncryptedDataFromSharedPrefs(          context: Context,          filename: String,          mode: Int,          prefKey: String      ): EncryptedData?        fun isDataExistInSharedPrefs(context: Context, filename: String, mode: Int, prefKey: String): Boolean  }    fun CryptographyManager(): CryptographyManager = CryptographyManagerImpl()    data class EncryptedData(val ciphertext: ByteArray, val initializationVector: ByteArray)    private class CryptographyManagerImpl : CryptographyManager {        private val KEY_SIZE: Int = 256      val ANDROID_KEYSTORE = "AndroidKeyStore"      private val ENCRYPTION_BLOCK_MODE = KeyProperties.BLOCK_MODE_GCM      private val ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_NONE      private val ENCRYPTION_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES        override fun getInitializedCipherForEncryption(keyName: String): Cipher {          val cipher = getCipher()          val secretKey = getOrCreateSecretKey(keyName)          cipher.init(Cipher.ENCRYPT_MODE, secretKey)          return cipher      }        override fun getInitializedCipherForDecryption(keyName: String, initializationVector: ByteArray): Cipher {          val cipher = getCipher()          val secretKey = getOrCreateSecretKey(keyName)          cipher.init(Cipher.DECRYPT_MODE, secretKey, GCMParameterSpec(128, initializationVector))          return cipher      }        override fun encryptData(plaintext: String, cipher: Cipher): EncryptedData {          val ciphertext = cipher.doFinal(plaintext.toByteArray(Charset.forName("UTF-8")))          return EncryptedData(ciphertext,cipher.iv)      }        override fun decryptData(ciphertext: ByteArray, cipher: Cipher): String {          val plaintext = cipher.doFinal(ciphertext)          return String(plaintext, Charset.forName("UTF-8"))      }        override fun saveEncryptedDataToSharedPrefs(          encryptedData: EncryptedData,          context: Context,          filename: String,          mode: Int,          prefKey: String      ) {          val json = Gson().toJson(encryptedData)          context.getSharedPreferences(filename, mode).edit().putString(prefKey, json).apply()      }        override fun getEncryptedDataFromSharedPrefs(          context: Context,          filename: String,          mode: Int,          prefKey: String      ): EncryptedData? {          val json = context.getSharedPreferences(filename, mode).getString(prefKey, null)          return  Gson().fromJson(json, EncryptedData::class.java)      }        override fun isDataExistInSharedPrefs(          context: Context,          filename: String,          mode: Int,          prefKey: String      ): Boolean {          val pref = context.getSharedPreferences(filename, mode).getString(prefKey, null)          return pref != null      }        private fun getCipher(): Cipher {          val transformation = "$ENCRYPTION_ALGORITHM/$ENCRYPTION_BLOCK_MODE/$ENCRYPTION_PADDING"          return Cipher.getInstance(transformation)      }        private fun getOrCreateSecretKey(keyName: String): SecretKey {          // If Secretkey was previously created for that keyName, then grab and return it.          val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE)          keyStore.load(null) // Keystore must be loaded before it can be accessed          keyStore.getKey(keyName, null)?.let { return it as SecretKey }            // if you reach here, then a new SecretKey must be generated for that keyName          val paramsBuilder = KeyGenParameterSpec.Builder(keyName,              KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)          paramsBuilder.apply {              setBlockModes(ENCRYPTION_BLOCK_MODE)              setEncryptionPaddings(ENCRYPTION_PADDING)              setKeySize(KEY_SIZE)              setUserAuthenticationRequired(true)          }            val keyGenParams = paramsBuilder.build()          val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,              ANDROID_KEYSTORE)          keyGenerator.init(keyGenParams)          return keyGenerator.generateKey()      }  }  
https://stackoverflow.com/questions/67358706/how-to-use-lock-screen-password-instead-of-fingerprint May 03, 2021 at 12:27AM

没有评论:

发表评论