From dde2ff47a4b51ddd491aaaccdceae2a44ede90a6 Mon Sep 17 00:00:00 2001 From: dankito Date: Sat, 10 Oct 2020 01:37:50 +0200 Subject: [PATCH] Fixed that algorithms needed for encryption with biometric authentication are only supported on Android 6 and above (the same as with biometric authentication) --- .../authentication/AuthenticationService.kt | 11 ++++++++ .../android/security/CryptographyManager.kt | 26 ++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/authentication/AuthenticationService.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/authentication/AuthenticationService.kt index fd897fec..b3e0e0dd 100644 --- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/authentication/AuthenticationService.kt +++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/authentication/AuthenticationService.kt @@ -73,6 +73,11 @@ open class AuthenticationService( } open fun authenticateUserWithBiometricToSetAsNewAuthenticationMethod(authenticationResult: (AuthenticationResult) -> Unit) { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + authenticationResult(AuthenticationResult(false, "Biometric authentication is only supported on Android 6 and above")) + return + } + val cipher = cryptographyManager.getInitializedCipherForEncryption(EncryptionKeyName) biometricAuthenticationService.authenticate(cipher) { result -> @@ -85,6 +90,12 @@ open class AuthenticationService( } open fun authenticateUserWithBiometric(result: (Boolean) -> Unit) { + // Biometric authentication is only supported on Android 6 and above + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) { + result(false) + return + } + loadAuthenticationSettings()?.let { settings -> val iv = decodeFromBase64(settings.initializationVector ?: "") diff --git a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/security/CryptographyManager.kt b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/security/CryptographyManager.kt index 4e0a90a1..dce24c14 100644 --- a/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/security/CryptographyManager.kt +++ b/ui/BankingAndroidApp/src/main/java/net/dankito/banking/ui/android/security/CryptographyManager.kt @@ -3,8 +3,10 @@ package net.dankito.banking.ui.android.security import android.os.Build import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties +import androidx.annotation.RequiresApi import java.security.KeyStore import java.security.SecureRandom +import java.security.Security import javax.crypto.Cipher import javax.crypto.KeyGenerator import javax.crypto.SecretKey @@ -33,14 +35,17 @@ open class CryptographyManager { } + @RequiresApi(Build.VERSION_CODES.M) open fun getInitializedCipherForEncryption(keyName: String): Cipher { return getInitializedCipher(keyName, Cipher.ENCRYPT_MODE) } + @RequiresApi(Build.VERSION_CODES.M) open fun getInitializedCipherForDecryption(keyName: String, initializationVector: ByteArray): Cipher { return getInitializedCipher(keyName, Cipher.DECRYPT_MODE, initializationVector) } + @RequiresApi(Build.VERSION_CODES.M) protected open fun getInitializedCipher(keyName: String, cipherMode: Int, initializationVector: ByteArray? = null): Cipher { val cipher = Cipher.getInstance(CipherTransformation) val secretKey = getOrCreateSecretKey(keyName) @@ -50,16 +55,7 @@ open class CryptographyManager { return cipher } - - open fun encryptData(plaintext: String, cipher: Cipher): ByteArray { - return cipher.doFinal(plaintext.toByteArray(PasswordCharset)) - } - - open fun decryptData(cipherText: ByteArray, cipher: Cipher): String { - val plainTextBytes = cipher.doFinal(cipherText) - return String(plainTextBytes, PasswordCharset) - } - + @RequiresApi(Build.VERSION_CODES.M) protected open fun getOrCreateSecretKey(keyName: String): SecretKey { val keyStore = KeyStore.getInstance(AndroidKeyStore) keyStore.load(null) @@ -82,6 +78,16 @@ open class CryptographyManager { } + open fun encryptData(plaintext: String, cipher: Cipher): ByteArray { + return cipher.doFinal(plaintext.toByteArray(PasswordCharset)) + } + + open fun decryptData(cipherText: ByteArray, cipher: Cipher): String { + val plainTextBytes = cipher.doFinal(cipherText) + return String(plainTextBytes, PasswordCharset) + } + + open fun encryptDataWithPbe(plaintext: String, password: String, salt: ByteArray): Pair { val secret: SecretKey = generatePbeSecretKey(password, salt)