Sobes.tech
Back to questions
Middle
98
questionbank

Где бы вы хранили защищенные данные пользователя?

Sobes Copilot

Get answers in real time

Answer from AI

sobes.tech 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: "Document directory not found"]) }
    
        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
    }
    

Выбор места хранения зависит от:

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