Middle
Kur glabātu lietotāja aizsargātos datus?
sobes.tech AI
Atbilde no AI
iOS drošības datu glabāšanas vietas izvēle ir atkarīga no datu veida un drošības līmeņa:
-
Keychain Services:
- Ideāli piemērots neliela apjoma konfidenciālas informācijas glabāšanai, piemēram, paroles, autorizācijas žetoni, šifrēšanas atslēgas.
- Sistēmas demons
securitydpārvalda keychain un glabā datus šifrētā veidā uz diska. - Atbalsta dažādus pieejamības līmeņus (piemēram, pieejams tikai ierīces atbloķēšanas laikā).
- Dati automātiski sinhronizējas caur iCloud Keychain, ja tas ir aktivizēts.
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) // Dzēš esošo ierakstu return SecItemAdd(query as CFDictionary, nil) // Pievieno jaunu ierakstu } -
Encrypted Core Data / Realm:
- Piemērots strukturētu datu glabāšanai, kas prasa šifrēšanu datu bāzes līmenī.
- Core Data atbalsta trešo pušu paplašinājumus šifrēšanai (piemēram, RNCryptor).
- Realm datu bāzei ir iebūvēta faila šifrēšana.
- Šifrēšanas atslēga jāglabā Keychain.
// Realm šifrēšanas piemērs import RealmSwift func setupEncryptedRealm() throws { var config = Realm.Configuration() if let key = KeychainHelper.getRealmEncryptionKey() { // Iegūst atslēgu no Keychain config.encryptionKey = key } else { // Ģenerē jaunu atslēgu, saglabā un izmanto 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) // Izmanto Realm } -
File Protection APIs:
- Failu šifrēšanai, kas tiek glabāti lietotnes failu sistēmā.
- iOS automātiski šifrē failus līmeņa failu sistēmā, izmantojot Secure Enclave pārvaldītās atslēgas.
- Var iestatīt dažādus aizsardzības režīmus (piemēram,
complete,completeUnlessOpen,completeUntilFirstUserAuthentication,none), atkarībā no ierīces bloķēšanas stāvokļa.
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: "Dokumentu mape nav atrasta"]) let fileURL = documentDirectory.appendingPathComponent(fileName) // Iestatīt aizsardzības režīmu let options: Data.WritingOptions = .atomicWrite let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Piemērs, reālas opcijas tiek iestatītas ar faila atribūtiem vai info.plist try data.write(to: fileURL, options: options) // Faila sistēmas atribūtu iestatīšana (piemērs) var attributes: [FileAttributeKey : Any] = [:] attributes[.protectionKey] = FileProtectionType.complete try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path) } -
Secure Enclave:
- Aparatūras kopprocesors, atdalīts no galvenā procesora, paredzēts kriptogrāfisko atslēgu un datu glabāšanai un apstrādei.
- Izmanto Touch ID / Face ID un citas jutīgas operācijas.
- Atslēgas, kas glabājas Secure Enclave, nekad neiziet no tās un nav pieejamas galvenajam procesoram vai operētājsistēmai.
- Ideāli piemērots raktu ģenerēšanai, glabāšanai un izmantošanai parakstīšanai vai šifrēšanai, kur svarīga ir programmatūras uzbrukumu aizsardzība.
import CryptoKit import LocalAuthentication func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey { let accessControl = SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Pieejams tikai ar paroli [.userPresence], // Nepieciešama lietotāja autentifikācija (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, // Atslēga būs pastāvīga kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Unikāls marķētājs kSecAttrAccessControl as String: accessControl ] ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } // Var iegūt atslēgas no Secure Enclave pēc marķētāja izmantošanas return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Piemērs, nepieciešama pārvēršana no SecKey uz Data }
Izvēle ir atkarīga no:
- Datu apjoma (mazs vs strukturēti dati)
- Datu veida (parole vs fails vs kriptogrāfiska atslēga)
- Aizsardzības līmeņa
- Sinhronizācijas nepieciešamības starp ierīcēm (Keychain)
- Lietotāja autentifikācijas nepieciešamības (Secure Enclave, File Protection)