diff --git a/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift b/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift index 3c237e93..c042dde9 100644 --- a/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift +++ b/ui/BankingiOSApp/BankingiOSApp/Security/AuthenticationService.swift @@ -1,5 +1,6 @@ import SwiftUI import LocalAuthentication +import CryptoSwift import BankingUiSwift @@ -95,13 +96,18 @@ class AuthenticationService { } func authenticateUserWithPassword(_ enteredPassword: String, _ authenticationResult: @escaping (Bool, String?) -> Void) { - if retrieveLoginPassword() == enteredPassword { - let decryptDatabaseResult = openDatabase(false, enteredPassword) - authenticationResult(decryptDatabaseResult, nil) - } - else { - authenticationResult(false, "Incorrect password entered".localize()) + if let storedHash = readLoginPasswordHash() { + if let hashOfEnteredPassword = hashLoginPassword(enteredPassword) { + if storedHash == hashOfEnteredPassword { + let decryptDatabaseResult = openDatabase(false, enteredPassword) + authenticationResult(decryptDatabaseResult, nil) + + return + } + } } + + authenticationResult(false, "Incorrect password entered".localize()) } @discardableResult @@ -291,11 +297,13 @@ class AuthenticationService { @discardableResult private func setLoginPassword(_ newPassword: String) -> Bool { do { - let passwordItem = createUserLoginPasswordKeychainItem() - - try passwordItem.savePassword(newPassword) - - return true + if let passwordHash = hashLoginPassword(newPassword) { + let passwordItem = createUserLoginPasswordKeychainItem() + + try passwordItem.savePassword(passwordHash) + + return true + } } catch { NSLog("Could not save login password: \(error)") } @@ -303,6 +311,18 @@ class AuthenticationService { return false } + private func readLoginPasswordHash() -> String? { + do { + let passwordItem = createUserLoginPasswordKeychainItem() + + return try passwordItem.readPassword() + } catch { + NSLog("Could not read login password: \(error)") + } + + return nil + } + @discardableResult private func deleteLoginPassword() -> Bool { do { @@ -318,18 +338,6 @@ class AuthenticationService { return false } - private func retrieveLoginPassword() -> String? { - do { - let passwordItem = createUserLoginPasswordKeychainItem() - - return try passwordItem.readPassword() - } catch { - NSLog("Could not read login password: \(error)") - } - - return nil - } - private func createUserLoginPasswordKeychainItem() -> KeychainPasswordItem { return KeychainPasswordItem(Self.UserLoginPasswordKeychainAccountName) } @@ -352,6 +360,22 @@ class AuthenticationService { } + private func hashLoginPassword(_ loginPassword: String) -> String? { + do { + let password = Array(loginPassword.utf8) + //let salt = Array(generateRandomPassword(8).utf8) + let salt = Array("aaaaaaaa".utf8) + + let bytes = try Scrypt(password: password, salt: salt, dkLen: 64, N: 256, r: 8, p: 1).calculate() + + return bytes.toBase64() + } catch { + NSLog("Could not create hash for login password: \(error)") + } + + return nil + } + private func concatPasswords(_ loginPassword: String, _ defaultPassword: String) -> String { return loginPassword + "_" + defaultPassword }