Middle
Къде бихте съхранявали защитените данни на потребителя?
sobes.tech AI
Отговор от AI
За съхранение на защитени потребителски данни на iOS бих използвал следните места, в зависимост от типа данни и нивото на сигурност:
-
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) // Добавяне на нов запис } -
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 } -
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) } -
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).