Implemented encrypting AuthenticationType and default password

This commit is contained in:
dankito 2020-10-14 03:15:59 +02:00
parent 50ae70a92c
commit 81bc6a94bb
1 changed files with 62 additions and 14 deletions

View File

@ -14,6 +14,10 @@ class AuthenticationService {
static private let UserLoginPasswordSaltKeychainAccountName = "UserLoginPasswordSalt"
static private let Key = ">p(Z5&RRA,@_+W0#" // length = 16 // TODO: find a better way to store key
static private let IV = "drowssapdrowssap" // length = 16
private let biometricAuthenticationService = BiometricAuthenticationService()
private let persistence: IBankingPersistence
@ -86,6 +90,7 @@ class AuthenticationService {
}
// TODO: big bug, in this way it's not possible to set a new password with biometrics
func authenticateUserWithBiometric(_ prompt: String, _ authenticationResult: @escaping (Bool, String?) -> Void) {
biometricAuthenticationService.authenticate(prompt) { successful, error in
var decryptDatabaseResult = false
@ -97,6 +102,8 @@ class AuthenticationService {
}
}
// TODO: implement authenticateUserWithBiometricToSetAsNewAuthenticationMethod()
func authenticateUserWithPassword(_ enteredPassword: String, _ authenticationResult: @escaping (Bool, String?) -> Void) {
if let storedHash = readLoginPasswordHash() {
if let salt = readLoginPasswordSalt() {
@ -151,9 +158,9 @@ class AuthenticationService {
do {
let authenticationTypeItem = createAuthenticationTypeKeychainItem()
let authenticationTypeString = try authenticationTypeItem.readPassword()
return AuthenticationType.init(rawValue: authenticationTypeString)
if let authenticationTypeString = try decrypt(authenticationTypeItem.readPassword()) {
return AuthenticationType.init(rawValue: authenticationTypeString)
}
} catch {
NSLog("Could not read AuthenticationType: \(error)")
}
@ -167,9 +174,11 @@ class AuthenticationService {
}
do {
let authenticationTypeItem = createAuthenticationTypeKeychainItem()
if let encrypted = encrypt(type.rawValue) {
let authenticationTypeItem = createAuthenticationTypeKeychainItem()
try authenticationTypeItem.savePassword(type.rawValue)
try authenticationTypeItem.savePassword(encrypted)
}
} catch {
NSLog("Could not save AuthenticationType: \(error)")
}
@ -203,8 +212,8 @@ class AuthenticationService {
var databasePassword = currentPassword ?? ""
if let currentPassword = currentPassword {
try passwordItem.savePassword(currentPassword)
if let currentPassword = currentPassword, let encryped = encrypt(currentPassword) {
try passwordItem.savePassword(encryped)
}
else {
if let newDefaultPassword = createNewDefaultPassword(useBiometricAuthentication) {
@ -230,11 +239,13 @@ class AuthenticationService {
do {
let newDefaultPassword = generateRandomPassword(30)
let passwordItem = createDefaultPasswordKeychainItem(useBiometricAuthentication)
if let encrypedNewDefaultPassword = encrypt(newDefaultPassword) {
let passwordItem = createDefaultPasswordKeychainItem(useBiometricAuthentication)
try passwordItem.savePassword(newDefaultPassword)
try passwordItem.savePassword(encrypedNewDefaultPassword)
return newDefaultPassword
return newDefaultPassword
}
} catch {
NSLog("Could not create new default password: \(error)")
}
@ -246,7 +257,7 @@ class AuthenticationService {
do {
let passwordItem = createDefaultPasswordKeychainItem(useBiometricAuthentication)
return try passwordItem.readPassword()
return try decrypt(passwordItem.readPassword())
} catch {
NSLog("Could not read default password: \(error)")
}
@ -409,6 +420,8 @@ class AuthenticationService {
deleteDefaultPassword(true)
deleteLoginPassword()
deleteLoginPasswordSalt()
}
@ -419,6 +432,41 @@ class AuthenticationService {
}
private func encrypt(_ string: String) -> String? {
do {
let cipher = try getCipher()
let cipherText = try cipher.encrypt(Array(string.utf8))
return cipherText.toBase64()
} catch {
NSLog("Could not encrypt value: \(error)")
}
return nil
}
private func decrypt(_ base64EncodedCipherText: String) -> String? {
do {
let bytes = Array<UInt8>(base64: base64EncodedCipherText)
let cipher = try getCipher()
let decryptedBytes = try cipher.decrypt(bytes)
return String(bytes: decryptedBytes, encoding: .utf8)
} catch {
NSLog("Could not decrypt cipher text: \(error)")
}
return nil
}
private func getCipher() throws -> AES {
return try AES(key: Self.Key, iv: Self.IV)
}
private func hashLoginPassword(_ loginPassword: String, _ salt: Array<UInt8>) -> String? {
do {
let password = Array(loginPassword.utf8)