Sobes.tech
Middle

Kde by ste ukladali chránené údaje používateľa?

sobes.tech AI

Odpoveď od AI

Pre bezpečného uloženia chránených používateľských údajov na iOS by som použil nasledujúce miesta v závislosti od typu údajov a úrovne zabezpečenia:

  1. Keychain Services:

    • Ideálne na uloženie malých objemov dôverných informácií, ako sú heslá, autorizačné tokeny, šifrovacie kľúče.
    • Systémový démon securityd spravuje keychain a uchováva údaje zašifrované na disku.
    • Podporuje rôzne úrovne dostupnosti (napríklad dostupné iba pri odomknutom zariadení).
    • Údaje sa automaticky synchronizujú cez iCloud Keychain, ak je zapnuté.
    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) // Odstránenie existujúceho záznamu
        return SecItemAdd(query as CFDictionary, nil) // Pridanie nového záznamu
    }
    
  2. Encrypted Core Data / Realm:

    • Pre uloženie štruktúrovaných údajov, ktoré vyžadujú šifrovanie na úrovni databázy.
    • Core Data podporuje externé rozšírenia pre šifrovanie (napríklad RNCryptor).
    • Realm Database má vstavané šifrovanie súboru databázy.
    • Kľúč šifrovania by mal byť uložený v Keychain.
    // Príklad inicializácie Realm s šifrovaním
    import RealmSwift
    
    func setupEncryptedRealm() throws {
        var config = Realm.Configuration()
        if let key = KeychainHelper.getRealmEncryptionKey() { // Získanie kľúča z Keychain
            config.encryptionKey = key
        } else {
            // Generovanie nového kľúča, uloženie do Keychain a použitie
            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)
        // Použitie Realm
    }
    
  3. File Protection APIs:

    • Pre šifrovanie súborov uložených v súborovom systéme aplikácie.
    • iOS automaticky šifruje súbory na úrovni súborového systému pomocou kľúčov, ktoré spravuje Secure Enclave.
    • Môžu sa nastaviť rôzne režimy ochrany (napríklad, complete, completeUnlessOpen, completeUntilFirstUserAuthentication, none) na kontrolu prístupu v závislosti od stavu zamknutia zariadenia.
    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: "Dokumentárny adresár nenalezen"]) }
    
        let fileURL = documentDirectory.appendingPathComponent(fileName)
    
        // Nastavenie režimu ochrany
        let options: Data.WritingOptions = .atomicWrite
        let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Len príklad, skutočné možnosti ochrany sa nastavujú atribútmi súboru alebo v info.plist
    
        try data.write(to: fileURL, options: options)
    
        // Nastavenie atribútov ochrany súborového systému (príklad)
        var attributes: [FileAttributeKey : Any] = [:]
        attributes[.protectionKey] = FileProtectionType.complete
        try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path)
    }
    
  4. Secure Enclave:

    • Hardvérový koprocesor, oddelený od hlavného procesora, určený na ukladanie a spracovanie kryptografických kľúčov a údajov.
    • Používa sa pre Touch ID / Face ID a ďalšie citlivé operácie.
    • Kľúče uložené v Secure Enclave nikdy neopúšťajú jeho prostredie a nie sú dostupné hlavného procesoru alebo operačnému systému.
    • Ideálne na generovanie, ukladanie a používanie kľúčov na podpísanie alebo šifrovanie, kde je dôležitá ochrana pred softvérovými útokmi.
    import CryptoKit
    import LocalAuthentication
    
    func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey {
        let accessControl = SecAccessControlCreateWithFlags(
            kCFAllocatorDefault,
            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Prístupné pri nastavenom hesle
            [.userPresence], // Vyžaduje autentifikáciu používateľa (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, // Kľúč bude trvalý
                kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Unikátny štítok
                kSecAttrAccessControl as String: accessControl
            ]
        ]
    
        var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }
    
        // Môžete získať kľúče zo Secure Enclave podľa štítku na použitie
        return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Príklad, je potrebné konvertovať z SecKey na Data
    }
    

Výber miesta uloženia závisí od:

  • Veľkosti údajov (malý objem vs štruktúrované údaje).
  • Typu údajov (heslo vs súbor vs kryptografický kľúč).
  • Požadovanej úrovne ochrany.
  • Potreby synchronizácie medzi zariadeniami (Keychain).
  • Potreby autentifikácie používateľa na prístup (Secure Enclave, File Protection).