Fixed that algorithms needed for encryption with biometric authentication are only supported on Android 6 and above (the same as with biometric authentication)
This commit is contained in:
parent
06101a4e57
commit
dde2ff47a4
|
@ -73,6 +73,11 @@ open class AuthenticationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun authenticateUserWithBiometricToSetAsNewAuthenticationMethod(authenticationResult: (AuthenticationResult) -> Unit) {
|
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)
|
val cipher = cryptographyManager.getInitializedCipherForEncryption(EncryptionKeyName)
|
||||||
|
|
||||||
biometricAuthenticationService.authenticate(cipher) { result ->
|
biometricAuthenticationService.authenticate(cipher) { result ->
|
||||||
|
@ -85,6 +90,12 @@ open class AuthenticationService(
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun authenticateUserWithBiometric(result: (Boolean) -> Unit) {
|
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 ->
|
loadAuthenticationSettings()?.let { settings ->
|
||||||
val iv = decodeFromBase64(settings.initializationVector ?: "")
|
val iv = decodeFromBase64(settings.initializationVector ?: "")
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,10 @@ package net.dankito.banking.ui.android.security
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.security.keystore.KeyGenParameterSpec
|
import android.security.keystore.KeyGenParameterSpec
|
||||||
import android.security.keystore.KeyProperties
|
import android.security.keystore.KeyProperties
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
import java.security.Security
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
import javax.crypto.KeyGenerator
|
import javax.crypto.KeyGenerator
|
||||||
import javax.crypto.SecretKey
|
import javax.crypto.SecretKey
|
||||||
|
@ -33,14 +35,17 @@ open class CryptographyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
open fun getInitializedCipherForEncryption(keyName: String): Cipher {
|
open fun getInitializedCipherForEncryption(keyName: String): Cipher {
|
||||||
return getInitializedCipher(keyName, Cipher.ENCRYPT_MODE)
|
return getInitializedCipher(keyName, Cipher.ENCRYPT_MODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
open fun getInitializedCipherForDecryption(keyName: String, initializationVector: ByteArray): Cipher {
|
open fun getInitializedCipherForDecryption(keyName: String, initializationVector: ByteArray): Cipher {
|
||||||
return getInitializedCipher(keyName, Cipher.DECRYPT_MODE, initializationVector)
|
return getInitializedCipher(keyName, Cipher.DECRYPT_MODE, initializationVector)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
protected open fun getInitializedCipher(keyName: String, cipherMode: Int, initializationVector: ByteArray? = null): Cipher {
|
protected open fun getInitializedCipher(keyName: String, cipherMode: Int, initializationVector: ByteArray? = null): Cipher {
|
||||||
val cipher = Cipher.getInstance(CipherTransformation)
|
val cipher = Cipher.getInstance(CipherTransformation)
|
||||||
val secretKey = getOrCreateSecretKey(keyName)
|
val secretKey = getOrCreateSecretKey(keyName)
|
||||||
|
@ -50,16 +55,7 @@ open class CryptographyManager {
|
||||||
return cipher
|
return cipher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun getOrCreateSecretKey(keyName: String): SecretKey {
|
protected open fun getOrCreateSecretKey(keyName: String): SecretKey {
|
||||||
val keyStore = KeyStore.getInstance(AndroidKeyStore)
|
val keyStore = KeyStore.getInstance(AndroidKeyStore)
|
||||||
keyStore.load(null)
|
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<ByteArray, ByteArray> {
|
open fun encryptDataWithPbe(plaintext: String, password: String, salt: ByteArray): Pair<ByteArray, ByteArray> {
|
||||||
val secret: SecretKey = generatePbeSecretKey(password, salt)
|
val secret: SecretKey = generatePbeSecretKey(password, salt)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue