Middle
Où stockeriez-vous les données protégées de l'utilisateur?
sobes.tech IA
Réponse de l'IA
Pour stocker les données protégées de l'utilisateur sur iOS, j'utiliserais les emplacements suivants, en fonction du type de données et du niveau de sécurité :
-
Keychain Services :
- Idéal pour stocker de petites quantités d'informations confidentielles, telles que mots de passe, jetons d'autorisation, clés de chiffrement.
- Le démon système
securitydgère le keychain et stocke les données chiffrées sur le disque. - Supporte différents niveaux d'accessibilité (par exemple, disponible uniquement lorsque l'appareil est déverrouillé).
- Les données se synchronisent automatiquement via iCloud Keychain, si activé.
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) // Supprimer l'entrée existante return SecItemAdd(query as CFDictionary, nil) // Ajouter la nouvelle } -
Core Data chiffré / Realm :
- Pour stocker des données structurées nécessitant un chiffrement au niveau de la base de données.
- Core Data supporte des extensions tierces pour le chiffrement (par exemple, RNCryptor).
- Realm Database possède un chiffrement intégré des fichiers de base de données.
- La clé de chiffrement doit être stockée dans le Keychain.
// Exemple d'initialisation de Realm avec chiffrement import RealmSwift func setupEncryptedRealm() throws { var config = Realm.Configuration() if let key = KeychainHelper.getRealmEncryptionKey() { // Récupère la clé depuis le Keychain config.encryptionKey = key } else { // Génère une nouvelle clé, la stocke dans le Keychain et l'utilise 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) // Utiliser Realm } -
API de protection de fichiers :
- Pour chiffrer les fichiers stockés dans le système de fichiers de l'application.
- iOS chiffre automatiquement les fichiers au niveau du système de fichiers à l'aide de clés gérées par Secure Enclave.
- Il est possible de définir différents modes de protection (par exemple,
complete,completeUnlessOpen,completeUntilFirstUserAuthentication,none) pour contrôler l'accès en fonction de l'état du verrouillage de l'appareil.
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: "Répertoire de documents non trouvé"]) } let fileURL = documentDirectory.appendingPathComponent(fileName) // Définir le mode de protection let options: Data.WritingOptions = .atomicWrite let protectedOptions: Data.WritingOptions = options.union(.writingWithoutOverwriting) // Juste un exemple, les options réelles de protection sont définies par des attributs de fichier ou dans info.plist try data.write(to: fileURL, options: options) // Définir les attributs de protection du système de fichiers (exemple) var attributes: [FileAttributeKey : Any] = [:] attributes[.protectionKey] = FileProtectionType.complete try fileManager.setAttributes(attributes, ofItemAtPath: fileURL.path) } -
Secure Enclave :
- Coprocesseur matériel, séparé du processeur principal, destiné à stocker et traiter des clés et données cryptographiques.
- Utilisé pour Touch ID / Face ID et d'autres opérations sensibles.
- Les clés stockées dans le Secure Enclave ne quittent jamais celle-ci et ne sont pas accessibles au processeur principal ou au système d'exploitation.
- Idéal pour générer, stocker et utiliser des clés pour la signature ou le chiffrement, où la protection contre les attaques logicielles est importante.
import CryptoKit import LocalAuthentication func generateAndStoreKeyInSecureEnclave() throws -> P256.Signing.PrivateKey { let accessControl = SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, // Disponible lorsque le mot de passe est défini [.userPresence], // Nécessite l'authentification de l'utilisateur (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 clé sera permanente kSecAttrApplicationTag as String: "com.yourapp.signingkey".data(using: .utf8)!, // Étiquette unique kSecAttrAccessControl as String: accessControl ] ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else { throw error!.takeRetainedValue() as Error } // La clé peut être récupérée du Secure Enclave par l'étiquette pour utilisation return try P256.Signing.PrivateKey(rawRepresentation: privateKeyData) // Exemple, nécessite conversion de SecKey en Data }
Le choix de l'emplacement de stockage dépend de :
- La taille des données (petite vs données structurées).
- Le type de données (mot de passe vs fichier vs clé cryptographique).
- Le niveau de protection requis.
- La nécessité de synchronisation entre appareils (Keychain).
- La nécessité d'authentification de l'utilisateur pour l'accès (Secure Enclave, protection de fichiers).