Implemented encrypting authentication settings file

This commit is contained in:
dankito 2020-11-07 02:11:30 +01:00
parent 0525872c05
commit 681b37d589
4 changed files with 33 additions and 4 deletions

View File

@ -66,6 +66,8 @@ ext {
zxingVersion = "3.3.0" zxingVersion = "3.3.0"
scytaleVersion = "1.0.1"
multiDexVersion = "2.0.1" multiDexVersion = "2.0.1"
appCompatVersion = "1.1.0" appCompatVersion = "1.1.0"

View File

@ -108,9 +108,11 @@ dependencies {
implementation "com.otaliastudios:autocomplete:$autocompleteVersion" implementation "com.otaliastudios:autocomplete:$autocompleteVersion"
implementation("com.journeyapps:zxing-android-embedded:4.1.0") { transitive = false } // transitive to use older Zxing version as ZXing 3.4.0 requires Android > 23 implementation("com.journeyapps:zxing-android-embedded:4.1.0") { transitive = false } // transitive to use older ZXing version as ZXing 3.4.0 requires Android > 23
implementation "com.google.zxing:core:$zxingVersion" implementation "com.google.zxing:core:$zxingVersion"
implementation "com.yakivmospan:scytale:$scytaleVersion"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutinesVersion"

View File

@ -1,7 +1,11 @@
package net.dankito.banking.ui.android.authentication package net.dankito.banking.ui.android.authentication
import android.content.Context
import android.util.Base64 import android.util.Base64
import at.favre.lib.crypto.bcrypt.BCrypt import at.favre.lib.crypto.bcrypt.BCrypt
import com.yakivmospan.scytale.Crypto
import com.yakivmospan.scytale.Options
import com.yakivmospan.scytale.Store
import net.dankito.banking.persistence.IBankingPersistence import net.dankito.banking.persistence.IBankingPersistence
import net.dankito.banking.ui.android.security.CryptographyManager import net.dankito.banking.ui.android.security.CryptographyManager
import net.dankito.banking.util.ISerializer import net.dankito.banking.util.ISerializer
@ -9,9 +13,11 @@ import net.dankito.utils.multiplatform.File
import net.dankito.utils.multiplatform.asString import net.dankito.utils.multiplatform.asString
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import javax.crypto.Cipher import javax.crypto.Cipher
import javax.crypto.SecretKey
open class AuthenticationService( open class AuthenticationService(
protected open val applicationContext: Context,
protected open val biometricAuthenticationService: IBiometricAuthenticationService, protected open val biometricAuthenticationService: IBiometricAuthenticationService,
protected open val persistence: IBankingPersistence, protected open val persistence: IBankingPersistence,
protected open val dataFolder: File, protected open val dataFolder: File,
@ -22,6 +28,10 @@ open class AuthenticationService(
companion object { companion object {
private const val AuthenticationSettingsFilename = "a" private const val AuthenticationSettingsFilename = "a"
private const val AuthenticationSettingsFileKey = "AuthenticationSettingsFileKey"
private val AuthenticationSettingsFileKeyPassword = "AuthenticationSettingsFileKeyAuthenticationSettingsFileKeyPassword".toCharArray() // TODO: store in a secure place
private const val EncryptionKeyName = "BankingAndroidKey" private const val EncryptionKeyName = "BankingAndroidKey"
private const val DefaultPasswordEncryptionKey = "AnyData" // TODO: store in a secure place private const val DefaultPasswordEncryptionKey = "AnyData" // TODO: store in a secure place
@ -219,7 +229,10 @@ open class AuthenticationService(
val file = File(dataFolder, AuthenticationSettingsFilename) val file = File(dataFolder, AuthenticationSettingsFilename)
if (file.exists()) { if (file.exists()) {
val json = file.readText() val (key, crypto) = getAuthenticationSettingsFileKey()
val encryptedJson = file.readText()
val json = crypto.decrypt(encryptedJson, key)
return serializer.deserializeObject(json, AuthenticationSettings::class) return serializer.deserializeObject(json, AuthenticationSettings::class)
} }
@ -233,9 +246,12 @@ open class AuthenticationService(
protected open fun saveAuthenticationSettings(settings: AuthenticationSettings): Boolean { protected open fun saveAuthenticationSettings(settings: AuthenticationSettings): Boolean {
try { try {
serializer.serializeObjectToString(settings)?.let { json -> serializer.serializeObjectToString(settings)?.let { json ->
val (key, crypto) = getAuthenticationSettingsFileKey()
val encryptedJson = crypto.encrypt(json, key)
val file = File(dataFolder, AuthenticationSettingsFilename) val file = File(dataFolder, AuthenticationSettingsFilename)
file.writeText(json) file.writeText(encryptedJson)
return true return true
} }
@ -246,6 +262,15 @@ open class AuthenticationService(
return false return false
} }
protected open fun getAuthenticationSettingsFileKey(): Pair<SecretKey, Crypto> {
val store = Store(applicationContext)
val key = if (store.hasKey(AuthenticationSettingsFileKey)) store.getSymmetricKey(AuthenticationSettingsFileKey, AuthenticationSettingsFileKeyPassword)
else store.generateSymmetricKey(AuthenticationSettingsFileKey, AuthenticationSettingsFileKeyPassword)
return Pair(key, Crypto(Options.TRANSFORMATION_SYMMETRIC))
}
open fun generateRandomPassword(): CharArray { open fun generateRandomPassword(): CharArray {
return generateRandomPassword(30) return generateRandomPassword(30)

View File

@ -100,7 +100,7 @@ class BankingModule(private val applicationContext: Context) {
@Singleton @Singleton
fun provideAuthenticationService(biometricAuthenticationService: IBiometricAuthenticationService, persistence: IBankingPersistence, fun provideAuthenticationService(biometricAuthenticationService: IBiometricAuthenticationService, persistence: IBankingPersistence,
@Named(DataFolderKey) dataFolder: File, serializer: ISerializer) : AuthenticationService { @Named(DataFolderKey) dataFolder: File, serializer: ISerializer) : AuthenticationService {
return AuthenticationService(biometricAuthenticationService, persistence, dataFolder, serializer) return AuthenticationService(applicationContext, biometricAuthenticationService, persistence, dataFolder, serializer)
} }
@Provides @Provides