Comment chiffrer le contenu CoreData sur un iPhone

J’ai quelques informations que je voudrais stocker statiquement crypté sur une application iPhone. Je suis nouveau dans le développement de l’iPhone, certains que je ne connais pas très bien avec CoreData et comment il s’intègre aux vues. J’ai les données en JSON, bien que je puisse facilement les mettre dans une firebase database SQLITE3 ou dans tout autre format de données de sauvegarde. Je prendrai tout ce qui est le plus facile (a) à chiffrer et (b) à l’intégrer à la couche d’affichage de l’iPhone.

L’utilisateur devra saisir le mot de passe pour déchiffrer les données à chaque lancement de l’application. Le cryptage a pour but d’éviter que les données ne soient accessibles si l’utilisateur perd le téléphone.

Pour des raisons de rapidité, je préférerais chiffrer et déchiffrer tout le fichier en une fois plutôt que de chiffrer chaque champ de chaque ligne de la firebase database.

Remarque: l’idée n’est pas la même que celle de la question 929744 , qui vise à empêcher l’utilisateur de jouer avec ou de voir les données. Les données doivent être parfaitement transparentes lors de leur utilisation.

Notez également que je suis prêt à utiliser SQLCipher pour stocker les données, mais préférerais utiliser des choses qui existent déjà sur le framework iPhone / CoreData plutôt que de passer par le long processus de construction / intégration impliqué.

Vous pouvez chiffrer des propriétés individuelles dans vos entités de modèle Core Data en les transformant en propriétés , puis en créant une sous-classe NSValueTransformer qui chiffrera et déchiffrera les données de cette propriété. Bien que ce ne soit pas le déchiffrement de la firebase database complète que vous recherchez, son encombrement en mémoire est beaucoup plus faible que le déchiffrement d’une firebase database entière en mémoire. De plus, cela permettra au décryptage de se faire paresseusement, plutôt que par avance, de sorte que votre application se chargera beaucoup plus rapidement. Selon le chiffrement utilisé, je suppose même que les access aux données sur disque pour charger chaque entité seraient plus lents que le processus de déchiffrement des propriétés, de sorte que vous ne verriez pas une telle pénalité lors de l’access aux propriétés.

Les propriétés transformables comme celles-ci sont très faciles à utiliser, car vous leur lisez et écrivez normalement, tandis que le cryptage / décryptage se déroule en coulisse.

Avez-vous besoin de chiffrer? Les nouveaux iPhones (3Gs, 4, iPad…) chiffrent toutes les données sur l’appareil. Avec un seul mot de passe haché et salé sur votre application, personne ne peut accéder aux données sans mot de passe. Les données sont stockées en sandbox depuis toutes les autres applications.

Protection des données sur iOS

J’ai réussi à adapter le code exemple CustomAtomicStoreSubclass d’Apple pour l’utiliser dans une application de bureau Mac, aboutissant à un stockage persistant de style NSBinaryStore chiffré écrit sous la forme d’un fichier unique dans le système de fichiers. Mon approche:

  • Copiez le code source de la classe CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode dans mon projet et renommez-les
  • Stocker la clé et le vecteur initial dans le trousseau
  • Utilisez la bibliothèque OpenSSL fournie avec Mac OS X
  • Chiffrer la sortie NSKeyedArchiver et écrire le texte chiffré sur le disque (le déchiffrement est l’inverse)

J’ai intercepté les lectures et écritures du magasin de sauvegarde dans le readFile , metadataForPersistentStoreWithURL:error: setMetadata:forPersistentStoreWithURL:error: et save: dans CustomAtomicStoreSubclass .

Les notes de sous-classement pour la référence NSAtomicStore de l’iPhone sont similaires à celles de Mac OS X. Peut-être que cette approche pourrait également fonctionner avec l’iPhone.

Je sais que c’est une vieille question, mais elle est tout à fait pertinente et j’ai récemment dû aborder le sujet moi-même.

Les propriétés transformables sont une solution potentielle, mais ne semblent pas fonctionner avec NSPredicates, ce qui est un gros inconvénient. Je n’ai pas suivi l’approche CustomAtomicStoreSubclass, mais je suis curieux de savoir si d’autres personnes ont réussi.

Mes inquiétudes étaient similaires à celles de l’affiche originale et j’ai fini par faire ce qui suit:

  1. Déchiffrer le magasin dans un fichier temporaire
  2. Chargez le magasin déchiffré normalement
  3. Migrer le magasin vers un magasin en mémoire
  4. Supprimer le magasin non crypté

Dans mon cas, mon magasin était en lecture seule, mais cela pourrait être étendu pour réécrire le magasin, le chiffrer et supprimer à nouveau le magasin non chiffré. Vous pouvez également toujours ignorer le n ° 3 si vous avez un grand magasin et / ou si vous n’êtes pas préoccupé par la présence d’un fichier non crypté pendant que votre application est en cours d’exécution.

Le fichier Core Data avec lequel je travaillais était d’environ 1 Mo et pouvait être chiffré / déchiffré très rapidement.

J’utilise actuellement https://github.com/project-imas/encrypted-core-data pour chiffrer mon magasin coredata. Il s’agit d’une implémentation personnalisée de NSIncrementalStore. Il s’agit essentiellement d’un remplacement par la communauté du propre magasin persistant d’Apple qui dispose d’une option de chiffrement. C’est une solution intégrée qui fonctionne. Vous pouvez également sortir le fichier sqlite et le déchiffrer avec le code que vous choisissez parmi de nombreux clients différents.

L’implémentation ne dispose pas d’une couverture de 100% et ne permet pas certaines fonctionnalités telles que les prédicats de sous-requêtes. Je suis sur le sharepoint soumettre mon premier PR au repo pour espérer changer ça bientôt ;-). Je travaille presque toujours avec une application très complexe de coredata. Il a également l’avantage supplémentaire de vous permettre d’accéder directement à SQLite sans avoir à vous soucier de la modification de l’implémentation d’Apple puisque vous avez un access complet à la source.

“Le cryptage a pour but d’empêcher l’access aux données si l’utilisateur perd le téléphone.”

iOS dispose de la protection des données depuis iOS 4 et Core Data a pris en charge cette fonctionnalité pendant longtemps. La protection des données est conçue pour les types de scénarios qui vous intéressent. Par défaut, les fichiers Core Data NSSQLiteStoreType ont NSFileProtectionCompleteUntilFirstUserAuthentication pour les applications NSFileProtectionCompleteUntilFirstUserAuthentication avec l’API iOS 5 ou ultérieure. La session WWDC 2012 La protection des données de l’utilisateur est beaucoup plus détaillée dans cette rubrique et recommande d’utiliser NSFileProtectionComplete . Vous pouvez l’utiliser avec les données de base en transmettant cette valeur dans le dictionnaire d’options utilisé pour ouvrir votre magasin Core Data NSSQLiteStoreType .

Exemple:

 NSDictionary *storeOptions = @{ NSPersistentStoreFileProtectionKey : NSFileProtectionComplete }; if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:storeOptions error:&error]){ 

Le sujet plus large de la sécurité des appareils est traité dans iOS Security Device

Comment chiffrer ou déchiffrer les données?

“L’API Certificate, Key et Trust Services fournit des fonctions permettant de générer des clés de chiffrement symésortingques et asymésortingques, de créer et de vérifier des signatures numériques et de chiffrer des clés et des nonces. La bibliothèque CommonCrypto est utilisée pour le chiffrement symésortingque, le hachage et les opérations HMAC. , Key, et Trust Services Reference et les pages de manuel CC_crypto (3cc) pour plus d’informations. ”

Vous pouvez utiliser Trasformables, et je confirme, vous ne pouvez pas les utiliser avec des prédicats, mais (et c’est pire), vous ne pouvez même pas utiliser

… = [self primitiveValueForKey: @ “crypted_data”];

si vous utilisez des prédicats ..

cela fonctionne bien si vous cryptez vos données en utilisant:

 [self setPrimitiveValue:cryptedPsw forKey:@"crypted_data"]; 

pour crypter des données. (et par exemple sur le simulateur …. et avancer sur le bundle de projet plus tard ..)

Le cryptage est un cryptage, quel que soit le format de vos données, et vous n’avez certainement pas besoin de vous soucier de la manière dont «tout s’intègre avec les vues». Tout ce que vous avez à faire est de le décrypter avant d’essayer de lire quelque chose de significatif.