Sobes.tech
Middle

Unde ai stoca datele protejate ale utilizatorului?

sobes.tech AI

Răspuns de la AI

Pentru stocarea datelor protejate ale utilizatorului pe iOS, aș folosi următoarele locații, în funcție de tipul de date și nivelul de securitate:

  1. Keychain Services:

    • Ideal pentru stocarea unor cantități mici de informații confidențiale, cum ar fi parole, tokenuri de autorizare, chei de criptare.
    • Demonul sistem securityd gestionează keychain-ul și stochează datele într-un mod criptat pe disc.
    • Suportă diferite niveluri de accesibilitate (de exemplu, disponibil doar când dispozitivul este deblocat).
    • Datele sunt sincronizate automat prin iCloud Keychain, dacă este activat.
    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) // Șterge înregistrarea existentă
        return SecItemAdd(query as CFDictionary, nil) // Adaugă înregistrarea nouă
    }
    
  2. Core Data / Realm criptate:

    • Pentru stocarea datelor structurate, care necesită criptare la nivel de bază de date.
    • Core Data suportă extensii terțe pentru criptare (de exemplu, RNCryptor).
    • Realm Database are criptare încorporată a fișierului bazei de date.
    • Cheia de criptare trebuie stocată în Keychain.
    // Exemplu de inițializare Realm cu criptare
    import RealmSwift
    
    func setupEncryptedRealm() throws {
        var config = Realm.Configuration()
        if let key = KeychainHelper.getRealmEncryptionKey() { // Obține cheia din Keychain
            config.encryptionKey = key
        } else {
            // Generează o cheie nouă, o salvează în Keychain și o folosește
            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)
        // Folosește Realm
    }
    
  3. API-uri de protecție a fișierelor:

    • Pentru criptarea fișierelor stocate în sistemul de fișiere al aplicației.
    • iOS criptează automat fișierele la nivel de sistem de fișiere folosind chei gestionate de Secure Enclave.
    • Se pot seta diferite moduri de protecție (de exemplu, complete, completeUnlessOpen, completeUntilFirstUserAuthentication, none) pentru a controla accesul în funcție de starea de blocare a dispozitivului.
    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: "Directorul documentelor nu a fost găsit"]) }
    
        let fileURL = documentDirectory.appendingPathComponent(fileName)
    
        // Setează modul de protecție
        let options: Data.WritingOptions = .atomicWrite
        let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Exemplu, opțiunile reale de protecție sunt setate prin atributele fișierului sau în info.plist
    
        try data.write(to: fileURL, options: options)
    
        // Setează atributele de protecție ale sistemului de fișiere (exemplu)
        var attributes: [FileAttributeKey : Any] = [:]
        attributes[.protectionKey] = FileProtectionType.complete
        try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path)
    }
    
  4. Secure Enclave:

    • Procesor hardware, separat de procesorul principal, destinat stocării și procesării cheilor criptografice și datelor.
    • Folosit pentru Touch ID / Face ID și alte operațiuni sensibile.
    • Cheile stocate în Secure Enclave nu părăsesc niciodată această enclave și nu sunt accesibile procesorului principal sau sistemului de operare.
    • Ideal pentru generarea, stocarea și utilizarea cheilor pentru semnare sau criptare, unde protecția împotriva atacurilor software este importantă.
    import CryptoKit
    import LocalAuthentication
    
    func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey {
        let accessControl = SecAccessControlCreateWithFlags(
            kCFAllocatorDefault,
            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Accesibil dacă este setat un cod de acces
            [.userPresence], // Autentificare utilizator necesară (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, // Cheia va fi permanentă
                kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Etichetă unică
                kSecAttrAccessControl as String: accessControl
            ]
        ]
    
        var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }
    
        // Se pot obține cheile din Secure Enclave după etichetă pentru utilizare
        return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Exemplu, necesită conversie din SecKey în Data
    }
    

Alegerea locului de stocare depinde de:

  • Dimensiunea datelor (mică vs date structurate).
  • Tipul datelor (parolă vs fișier vs cheie criptografică).
  • Nivelul de protecție necesar.
  • Necesitatea sincronizării între dispozitive (Keychain).
  • Necesitatea autentificării utilizatorului pentru acces (Secure Enclave, File Protection).