Middle
Gde biste čuvali zaštićene podatke korisnika?
sobes.tech АИ
Одговор од АИ
Za čuvanje zaštićenih korisničkih podataka na iOS-u, koristio bih sledeća mesta u zavisnosti od tipa podataka i nivoa sigurnosti:
-
Keychain Services:
- Idealan za čuvanje malih količina poverljivih informacija, kao što su lozinke, tokeni za autorizaciju, šifrovani ključevi.
- Sistemski demon
securitydupravlja keychain-om i čuva podatke u šifrovanom obliku na disku. - Podržava različite nivoe dostupnosti (na primer, dostupno samo kada je uređaj otključan).
- Podaci se automatski sinhronizuju putem iCloud Keychain-a ako je uključeno.
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) // Briše postojeći zapis return SecItemAdd(query as CFDictionary, nil) // Dodaje novi zapis } -
Encrypted Core Data / Realm:
- Za skladištenje strukturiranih podataka koji zahtevaju šifrovanje na nivou baze podataka.
- Core Data podržava spoljne ekstenzije za šifrovanje (na primer, RNCryptor).
- Realm Database ima ugrađeno šifrovanje fajla baze podataka.
- Ključ šifrovanja treba čuvati u Keychain-u.
// Primer inicijalizacije Realm sa šifrovanjem import RealmSwift func setupEncryptedRealm() throws { var config = Realm.Configuration() if let key = KeychainHelper.getRealmEncryptionKey() { // Dobijanje ključa iz Keychain-a config.encryptionKey = key } else { // Generisanje novog ključa, čuvanje u Keychain i korišćenje 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) // Korišćenje Realm-a } -
File Protection APIs:
- Za šifrovanje fajlova koji se čuvaju u fajl sistemu aplikacije.
- iOS automatski šifruje fajlove na nivou fajl sistema pomoću ključeva koje upravlja Secure Enclave.
- Mogu se postaviti različiti režimi zaštite (na primer,
complete,completeUnlessOpen,completeUntilFirstUserAuthentication,none) za kontrolu pristupa u zavisnosti od stanja zaključavanja uređaja.
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: "Direktorijum za dokumente nije pronađen"]) } let fileURL = documentDirectory.appendingPathComponent(fileName) // Postavljanje režima zaštite let options: Data.WritingOptions = .atomicWrite let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Samo primer, stvarne opcije zaštite se postavljaju atributima fajla ili u info.plist try data.write(to: fileURL, options: options) // Postavljanje atributa zaštite fajl sistema (primer) var attributes: [FileAttributeKey : Any] = [:] attributes[.protectionKey] = FileProtectionType.complete try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path) } -
Secure Enclave:
- Hardverski koprocesor, odvojen od glavnog procesora, namenjen za čuvanje i obradu kriptografskih ključeva i podataka.
- Koristi se za Touch ID / Face ID i druge osetljive operacije.
- Ključevi koji se čuvaju u Secure Enclave nikada ne napuštaju njegovu sredinu i nisu dostupni glavnom procesoru ili operativnom sistemu.
- Idealan je za generisanje, čuvanje i korišćenje ključeva za potpisivanje ili šifrovanje, gde je zaštita od softverskih napada važna.
import CryptoKit import LocalAuthentication func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey { let accessControl = SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Dostupno kada je postavljen lozinka [.userPresence], // Potreban je autentikacija korisnika (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, // Ključ će biti trajni kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Jedinstveni tag kSecAttrAccessControl as String: accessControl ] ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } // Ključeve iz Secure Enclave možete dobiti putem taga za korišćenje return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Primer, potrebno je konvertovanje iz SecKey u Data }
Izbor mesta za skladištenje zavisi od:
- Veličine podataka (mali obim vs strukturirani podaci).
- Tipova podataka (lozinka vs fajl vs kriptografski ključ).
- Zahtevanog nivoa zaštite.
- Potrebe za sinhronizacijom između uređaja (Keychain).
- Potrebe za autentikacijom korisnika za pristup (Secure Enclave, File Protection).