Sobes.tech
Middle

Dove conserveresti i dati protetti dell'utente?

sobes.tech AI

Risposta dell'AI

Per memorizzare i dati protetti dell'utente su iOS, utilizzerei i seguenti luoghi, a seconda del tipo di dati e del livello di sicurezza:

  1. Keychain Services:

    • Ideale per memorizzare piccole quantità di informazioni riservate, come password, token di autorizzazione, chiavi di crittografia.
    • Il demone di sistema securityd gestisce il keychain e memorizza i dati in forma crittografata sul disco.
    • Supporta diversi livelli di accessibilità (ad esempio, disponibile solo quando il dispositivo è sbloccato).
    • I dati vengono sincronizzati automaticamente tramite iCloud Keychain, se abilitato.
    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) // Elimina la voce esistente
        return SecItemAdd(query as CFDictionary, nil) // Aggiunge la nuova voce
    }
    
  2. Core Data crittografato / Realm:

    • Per memorizzare dati strutturati che richiedono crittografia a livello di database.
    • Core Data supporta estensioni di terze parti per la crittografia (ad esempio, RNCryptor).
    • Realm Database ha la crittografia integrata del file di database.
    • La chiave di crittografia deve essere memorizzata nel Keychain.
    // Esempio di inizializzazione di Realm con crittografia
    import RealmSwift
    
    func setupEncryptedRealm() throws {
        var config = Realm.Configuration()
        if let key = KeychainHelper.getRealmEncryptionKey() { // Ottieni la chiave dal Keychain
            config.encryptionKey = key
        } else {
            // Genera una nuova chiave, salvala nel Keychain e usala
            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)
        // Usa Realm
    }
    
  3. API di Protezione File:

    • Per crittografare i file memorizzati nel filesystem dell'app.
    • iOS crittografa automaticamente i file a livello di filesystem usando chiavi gestite dal Secure Enclave.
    • È possibile impostare diversi modi di protezione (ad esempio, complete, completeUnlessOpen, completeUntilFirstUserAuthentication, none) per controllare l'accesso in base allo stato di blocco del dispositivo.
    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: "Directory dei documenti non trovata"]) }
    
        let fileURL = documentDirectory.appendingPathComponent(fileName)
    
        // Imposta il modo di protezione
        let options: Data.WritingOptions = .atomicWrite
        let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Solo un esempio, le opzioni di protezione reali sono impostate tramite attributi del file o in info.plist
    
        try data.write(to: fileURL, options: options)
    
        // Imposta attributi di protezione del filesystem (esempio)
        var attributes: [FileAttributeKey : Any] = [:]
        attributes[.protectionKey] = FileProtectionType.complete
        try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path)
    }
    
  4. Secure Enclave:

    • Coprocessore hardware, separato dal processore principale, destinato a memorizzare e processare chiavi e dati crittografici.
    • Utilizzato per Touch ID / Face ID e altre operazioni sensibili.
    • Le chiavi memorizzate nel Secure Enclave non ne escono mai e non sono accessibili al processore principale o al sistema operativo.
    • Ideale per generare, memorizzare e usare chiavi per firma o crittografia, dove la protezione da attacchi software è importante.
    import CryptoKit
    import LocalAuthentication
    
    func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey {
        let accessControl = SecAccessControlCreateWithFlags(
            kCFAllocatorDefault,
            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Disponibile quando è impostata la password
            [.userPresence], // È richiesta l'autenticazione dell'utente (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, // La chiave sarà permanente
                kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Etichetta unica
                kSecAttrAccessControl as String: accessControl
            ]
        ]
    
        var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }
    
        // È possibile ottenere le chiavi dal Secure Enclave tramite l'etichetta per l'uso
        return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Esempio, è richiesta la conversione da SecKey a Data
    }
    

La scelta del luogo di memorizzazione dipende da:

  • Dimensione dei dati (piccola vs dati strutturati).
  • Tipo di dati (password vs file vs chiave crittografica).
  • Livello di protezione richiesto.
  • Necessità di sincronizzazione tra dispositivi (Keychain).
  • Necessità di autenticazione dell'utente per l'accesso (Secure Enclave, Protezione File).