Sobes.tech
Middle

Къде бихте съхранявали защитените данни на потребителя?

sobes.tech AI

Отговор от AI

За съхранение на защитени потребителски данни на iOS бих използвал следните места, в зависимост от типа данни и нивото на сигурност:

  1. Keychain Services:

    • Идеално за съхранение на малки обеми поверителна информация, като пароли, токени за удостоверяване, ключове за криптиране.
    • Системният демон securityd управлява keychain и съхранява данните в криптиран вид на диска.
    • Поддържа различни нива на достъпност (например, достъпно само при отключено устройство).
    • Данните автоматично се синхронизират чрез iCloud Keychain, ако е включено.
    import Foundation
    import Security
    
    func savePassword(service: String, account: String, password: String) -> OSStatus {
        let data = password.data(using: .utf8)!
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: service,
            kSecAttrAccount as String: account,
            kSecValueData as String: data
        ]
    
        SecItemDelete(query as CFDictionary) // Изтриване на съществуващ запис
        return SecItemAdd(query as CFDictionary, nil) // Добавяне на нов запис
    }
    
  2. Encrypted Core Data / Realm:

    • За съхранение на структурирани данни, които изискват криптиране на ниво база данни.
    • Core Data поддържа външни разширения за криптиране (например RNCryptor).
    • Realm Database има вградена поддръжка за криптиране на файла на базата данни.
    • Ключът за криптиране трябва да се съхранява в Keychain.
    // Пример за инициализация на Realm с криптиране
    import RealmSwift
    
    func setupEncryptedRealm() throws {
        var config = Realm.Configuration()
        if let key = KeychainHelper.getRealmEncryptionKey() { // Получаване на ключ от Keychain
            config.encryptionKey = key
        } else {
            // Генериране на нов ключ, съхраняване в Keychain и използване
            let newKey = NSMutableData(length: 64)!
            _ = SecRandomCopyBytes(kSecRandomDefault, newKey.length, newKey.mutableBytes)
            KeychainHelper.saveRealmEncryptionKey(key: newKey as Data)
            config.encryptionKey = newKey as Data
        }
    
        let realm = try Realm(configuration: config)
        // Използване на Realm
    }
    
  3. File Protection APIs:

    • За криптиране на файлове, съхранявани във файловата система на приложението.
    • iOS автоматично криптира файловете на ниво файловата система с помощта на ключове, управлявани от Secure Enclave.
    • Могат да се зададат различни режими на защита (например, complete, completeUnlessOpen, completeUntilFirstUserAuthentication, none) за контрол на достъпа в зависимост от състоянието на блокиране на устройството.
    func saveProtectedDataToFile(data: Data, fileName: String) throws {
        let fileManager = FileManager.default
        let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
        guard let documentDirectory = urls.first else { throw NSError(domain: "MyApp", code: 1, userInfo: [NSLocalizedDescriptionKey: "Не е намерена директорията за документи"]) }
    
        let fileURL = documentDirectory.appendingPathComponent(fileName)
    
        // Настройка на режим на защита
        let options: Data.WritingOptions = .atomicWrite
        let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Просто пример, реалните опции за защита се задават чрез атрибути на файла или в info.plist
    
        try data.write(to: fileURL, options: options)
    
        // Задаване на атрибути за защита на файловата система (пример)
        var attributes: [FileAttributeKey : Any] = [:]
        attributes[.protectionKey] = FileProtectionType.complete
        try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path)
    }
    
  4. Secure Enclave:

    • Хардуерен съпроцесор, отделен от основния процесор, предназначен за съхранение и обработка на криптографски ключове и данни.
    • Използва се за Touch ID / Face ID и други чувствителни операции.
    • Ключовете, съхранявани в Secure Enclave, никога не напускат неговата среда и не са достъпни за основния процесор или операционната система.
    • Идеално подходящ за генериране, съхранение и използване на ключове за подписване или криптиране, където е важна защитата срещу софтуерни атаки.
    import CryptoKit
    import LocalAuthentication
    
    func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey {
        let accessControl = SecAccessControlCreateWithFlags(
            kCFAllocatorDefault,
            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Достъпно при зададен парола
            [.userPresence], // Изисква автентикация на потребителя (Touch ID/Face ID)
            nil
        )!
    
        let attributes: [String: Any] = [
            kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
            kSecAttrKeySizeInBits as String: 256,
            kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
            kSecPrivateKeyAttrs as String: [
                kSecAttrIsPermanent as String: true, // Ключът ще бъде постоянен
                kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Уникален таг
                kSecAttrAccessControl as String: accessControl
            ]
        ]
    
        var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }
    
        // Може да се получат ключовете от Secure Enclave по таг за използване
        return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Пример, изисква преобразуване от SecKey към Data
    }
    

Изборът на място за съхранение зависи от:

  • Размер на данните (малък обем срещу структурирани данни).
  • Тип на данните (парола срещу файл срещу криптографски ключ).
  • Изискваното ниво на защита.
  • Необходимостта от синхронизация между устройства (Keychain).
  • Необходимостта от автентикация на потребителя за достъп (Secure Enclave, File Protection).