J'ai quelques informations que je voudrais stocker cryptées statiquement sur une application iPhone. Je suis nouveau dans le développement iPhone, certains ne sont pas très familiers avec CoreData et son intégration aux vues. J'ai les données au format JSON, bien que je puisse facilement les insérer dans une base de données SQLITE3 ou dans tout autre format de sauvegarde. Je prendrai ce qui est le plus facile (a) à chiffrer et (b) à intégrer à la couche de visualisation 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 de garder les données inaccessibles si l'utilisateur perd le téléphone.
Pour des raisons de rapidité, je préférerais chiffrer et déchiffrer le fichier entier en une fois plutôt que de chiffrer chaque champ de chaque ligne de la base de données.
Remarque: ceci n'est pas la même idée que Question 929744 , dans laquelle l'objectif est d'empêcher l'utilisateur de modifier 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 éléments existants sur le framework iPhone/CoreData plutôt que de suivre le long processus de construction/intégration impliqué.
Vous pouvez chiffrer des propriétés individuelles dans les entités de votre modèle Core Data en les transformant propriétés transformables , 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 base de données complète que vous recherchiez, son empreinte mémoire sera bien moindre que celle du déchiffrement d’une base de données complète en mémoire. De plus, cela permettra au déchiffrement de se faire paresseusement plutôt que tout à l’avance, de sorte que votre application se chargera beaucoup plus rapidement. En fonction du chiffrement utilisé, je m'attendrais même à ce que les accès aux données sur disque pour le chargement de chaque entité soient plus lents que le processus de déchiffrement des propriétés. Par conséquent, vous ne constaterez pas une telle dégradation des performances lors de l'accès aux propriétés.
Les propriétés transformables telles que celle-ci sont très faciles à utiliser, car vous leur lisez et leur écrivez normalement, tandis que le cryptage/décryptage s'effectue en arrière-plan.
Avez-vous besoin de chiffrer? Les nouveaux iPhone (3G, 4, iPad ...) chiffrent toutes les données de 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 en mode bac à sable à partir de toutes les autres applications.
J'ai réussi à adapter le code CustomAtomicStoreSubclass example d'Apple à une application de bureau Mac, ce qui a abouti à la création d'un magasin persistant de style NSBinaryStore chiffré sous la forme d'un fichier unique dans le système de fichiers. Mon approche:
CustomAtomicStoreSubclass
& CustomAtomicStoreSubclassCacheNode
class dans mon projet et renommez-les.J'ai intercepté les lectures et écritures dans le magasin de support dans les méthodes readFile
, metadataForPersistentStoreWithURL:error:
, setMetadata:forPersistentStoreWithURL:error:
et save:
dans CustomAtomicStoreSubclass
.
Les notes de sous-classement de la référence de classe NSAtomicStore de l'iPhone sont similaires à celles de Mac OS X. Peut-être que cette approche pourrait également fonctionner avec l'iPhone.
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 est fondamentalement un remplacement de la communauté pour le propre magasin persistant d'Apple doté d'une option de cryptage. C'est une solution d'accueil qui fonctionne. Vous pouvez également extraire le fichier sqlite et le déchiffrer avec le code que vous avez choisi dans de nombreux clients.
L'implémentation n'a pas une couverture à 100% et ne permet pas certaines fonctionnalités telles que les prédicats de sous-requête. Je dois soumettre mon premier PR à la repo pour espérer que le changement intervienne bientôt ;-). Je l’ai presque complètement utilisé avec une application très complexe coredata. Il présente également l’avantage supplémentaire de vous permettre d’accéder directement à SQLite sans avoir à vous soucier de l’implémentation non négligeable de la mise en œuvre d’Apple puisque vous avez un accès complet à la source.
Je sais que c’est une vieille question, mais elle reste 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 semblaient pas fonctionner avec NSPredicates, ce qui constitue un gros inconvénient. Je n'ai pas suivi l'approche CustomAtomicStoreSubclass, mais je suis curieux de savoir si d'autres ont réussi.
Mes préoccupations étaient similaires à celles de l'affiche originale et j'ai finalement fini par:
Dans mon cas, mon magasin était en lecture seule, mais cela pouvait être étendu pour le réécrire, le chiffrer et supprimer à nouveau le magasin non chiffré. Vous pouvez également toujours ignorer le point 3 si vous avez un grand magasin et/ou que vous ne craignez pas de laisser un fichier non chiffré en attente pendant l'exécution de votre application.
Le fichier de données de base sur lequel je travaillais faisait environ 1 Mo et pouvait être chiffré/déchiffré très rapidement.
iOS a Protection des données depuis iOS 4, et Core Data le supporte depuis 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 construites avec l'API iOS 5 ou ultérieure. La session 2012 de la WWDC Protection des données de l'utilisateur aborde ce sujet plus en détail et vous recommande d'utiliser NSFileProtectionComplete
. Vous pouvez l'utiliser avec Core Data 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 général de la sécurité des appareils est traité dans iOS Device Security
Vous pouvez utiliser Trasformables, et je confirme, vous ne pouvez pas les utiliser avec des prédicats, mais
... = [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"];
chiffrer les données. (et par exemple sur le simulateur .... et passer plus tard au groupe de projets ..)
Comment chiffrer ou déchiffrer des données?
"L'API Services de certificats, de clés et de confiance fournit des fonctions permettant de générer des clés de chiffrement symétriques et asymétriques, de créer et de vérifier des signatures numériques, ainsi que de chiffrer des clés et des nonces. La bibliothèque CommonCrypto est utilisée pour le chiffrement symétrique, le hachage et les opérations HMAC. Voir Références de certificat, de clé et de confiance } et les CC_crypto (3cc) pages de manuel pour plus d'informations. "