Sobes.tech
Middle

Kus sa hoiaksid kasutaja kaitstud andmeid?

sobes.tech AI

Vastus AI-lt

iOS-i turvatud andmete salvestamise kohtade valik sõltub andmetest ja turvalisuse tasemest:

  1. Keychain Services:

    • Ideaalne väikese mahuga konfidentsiaalse teabe, näiteks paroolide, autoriseerimis- tokenite, krüptimisvõtmete salvestamiseks.
    • Süsteemi demon securityd haldab keychain'i ja hoiab andmeid krüpteeritud kujul kettal.
    • Toetab erinevaid ligipääsetaseme tasemeid (näiteks saadaval ainult seadme lukustamise ajal).
    • Andmed sünkroniseeritakse automaatselt iCloud Keychain'i kaudu, kui see on aktiveeritud.
    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) // Kustutab olemasoleva kirje
        return SecItemAdd(query as CFDictionary, nil) // Lisab uue kirje
    }
    
  2. Encrypted Core Data / Realm:

    • Sobib struktureeritud andmete salvestamiseks, mis nõuavad andmebaasi tasemel krüpteerimist.
    • Core Data toetab kolmanda osapoole laiendusi krüpteerimiseks (näiteks RNCryptor).
    • Realm andmebaasil on sisseehitatud faili krüpteerimise võimalus.
    • Krüptimise võti peab olema salvestatud Keychain'is.
    // Realm krüpteerimise näide
    import RealmSwift
    
    func setupEncryptedRealm() throws {
        var config = Realm.Configuration()
        if let key = KeychainHelper.getRealmEncryptionKey() { // Saab võtme Keychain'ist
            config.encryptionKey = key
        } else {
            // Genereerib uue võtme, salvestab ja kasutab
            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)
        // Kasutab Realm'i
    }
    
  3. File Protection APIs:

    • Failide krüpteerimiseks, mis salvestatakse rakenduse failisüsteemi:
    • iOS krüpteerib automaatselt failid failisüsteemi tasemel, kasutades Secure Enclave'i hallatavaid võtmeid.
    • Võib määrata erinevaid kaitse režiime (näiteks complete, completeUnlessOpen, completeUntilFirstUserAuthentication, none), sõltuvalt seadme lukustamise olekust.
    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: "Dokumendikaust ei leidu"])
    
        let fileURL = documentDirectory.appendingPathComponent(fileName)
    
        // Määrab kaitse režiimi
        let options: Data.WritingOptions = .atomicWrite
        let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Näide, tegelikud valikud määratakse faili atribuutide või info.plist kaudu
    
        try data.write(to: fileURL, options: options)
    
        // Failisüsteemi atribuutide määramine (näide)
        var attributes: [FileAttributeKey : Any] = [:]
        attributes[.protectionKey] = FileProtectionType.complete
        try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path)
    }
    
  4. Secure Enclave:

    • Seadme riistvaraline koostisosa, eraldatud peamisest protsessorist, mõeldud krüptovõtmete ja andmete salvestamiseks ning töötlemiseks.
    • Kasutatakse Touch ID / Face ID ja teiste tundlike operatsioonide jaoks.
    • Secure Enclave'is salvestatud võtmed ei lahku kunagi sealt ning ei ole kättesaadavad peamisele protsessorile ega operatsioonisüsteemile.
    • Ideaalne võtmete genereerimiseks, salvestamiseks ja kasutamiseks allkirjastamiseks või krüptimiseks, kus on oluline kaitse tarkvaraliste rünnakute eest.
    import CryptoKit
    import LocalAuthentication
    
    func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey {
        let accessControl = SecAccessControlCreateWithFlags(
            kCFAllocatorDefault,
            kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Saadaval ainult parooli seadmisel
            [.userPresence], // Nõutav kasutaja autentimine (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, // Võti on püsiv
                kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Unikaalne silt
                kSecAttrAccessControl as String: accessControl
            ]
        ]
    
        var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }
    
        // Võib saada võtmeid Secure Enclave'ist kasutamiseks
        return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Näide, nõuab teisendust SecKey-st Data'ks
    }
    

Valik sõltub:

  • Andmete suurusest (väike vs struktureeritud andmed)
  • Andmete tüübist (parool vs fail vs krüptovõti)
  • Nõutavast kaitse tasemest
  • Sünkroniseerimise vajadusest seadmete vahel (Keychain)
  • Kasutaja autentimise vajadusest (Secure Enclave, File Protection)