Sécurisation des données iOS au repos: chiffrement 1

Sécurisation des données iOS au repos: chiffrement

Dans cet article, nous examinerons les utilisations avancées du cryptage des données utilisateur dans les applications iOS. Nous commencerons par un examen de haut niveau du cryptage AES, puis nous examinerons quelques exemples de mise en œuvre du cryptage AES dans Swift.

Dans le dernier article, vous avez appris à stocker des données à l’aide du trousseau, ce qui est bon pour les petites informations telles que les clés, les mots de passe et les certificats.

Si vous stockez une grande quantité de données personnalisées que vous souhaitez rendre disponibles uniquement après l’authentification de l’utilisateur ou de l’appareil, il est préférable de chiffrer les données à l’aide d’une infrastructure de chiffrement. Par exemple, vous pouvez avoir une application qui peut archiver des messages de discussion privés enregistrés par l’utilisateur ou des photos privées prises par l’utilisateur, ou qui peut stocker les détails financiers de l’utilisateur. Dans ces cas, vous voudrez probablement utiliser le cryptage.

Il existe deux flux courants dans les applications pour chiffrer et déchiffrer les données des applications iOS. Soit l’utilisateur reçoit un écran de mot de passe, soit l’application est authentifiée auprès d’un serveur qui renvoie une clé pour déchiffrer les données.

Ce n’est jamais une bonne idée de réinventer la roue en matière de cryptage. Par conséquent, nous allons utiliser la norme AES fournie par la bibliothèque iOS Common Crypto.

AES

AES est une norme qui crypte les données à partir d’une clé. La même clé utilisée pour crypter les données est utilisée pour décrypter les données. Il existe différentes tailles de clé et AES256 (256 bits) est la longueur préférée à utiliser avec les données sensibles.

RNCryptor est un wrapper de chiffrement populaire pour iOS qui prend en charge AES. RNCryptor est un excellent choix car il vous permet d’être opérationnel très rapidement sans avoir à vous soucier des détails sous-jacents. Il est également open source afin que les chercheurs en sécurité puissent analyser et auditer le code.

D’un autre côté, si votre application traite des informations très sensibles et que vous pensez que votre application sera ciblée et fissurée, vous voudrez peut-être écrire votre propre solution. La raison en est que lorsque de nombreuses applications utilisent le même code, cela peut faciliter le travail du pirate informatique, en leur permettant d’écrire une application de piratage qui trouve des modèles communs dans le code et leur applique des correctifs.

Gardez à l’esprit, cependant, que l’écriture de votre propre solution ne fait que ralentir un attaquant et empêche les attaques automatisées. La protection que vous obtenez de votre propre implémentation est qu’un pirate informatique devra consacrer du temps et du dévouement à craquer seul votre application.

Que vous choisissiez une solution tierce ou que vous choisissiez de lancer la vôtre, il est important de bien connaître le fonctionnement des systèmes de chiffrement. De cette façon, vous pouvez décider si un framework particulier que vous souhaitez utiliser est vraiment sécurisé. Par conséquent, le reste de ce didacticiel se concentrera sur l’écriture de votre propre solution personnalisée. Avec les connaissances que vous apprendrez de ce didacticiel, vous serez en mesure de savoir si vous utilisez un framework particulier en toute sécurité.

Nous commencerons par la création d’une clé secrète qui sera utilisée pour crypter vos données.

Créer une clé

Une erreur très courante dans le cryptage AES est d’utiliser le mot de passe d’un utilisateur directement comme clé de cryptage. Que faire si l’utilisateur décide d’utiliser un mot de passe commun ou faible? Comment forcer les utilisateurs à utiliser une clé aléatoire et suffisamment forte (qui a suffisamment d’entropie) pour le chiffrement, puis à leur en souvenir?

La solution est étirement des touches. L’étirement de clé dérive une clé d’un mot de passe par hachage plusieurs fois avec un sel. Le sel n’est qu’une séquence de données aléatoires, et c’est une erreur courante d’omettre ce sel – le sel donne à la clé son entropie d’une importance vitale, et sans le sel, la même clé serait dérivée si le même mot de passe était utilisé par quelqu’un autre.

Sans le sel, un dictionnaire de mots pourrait être utilisé pour déduire des clés communes, qui pourraient ensuite être utilisées pour attaquer les données des utilisateurs. C’est ce qu’on appelle une « attaque par dictionnaire ». Des tables avec des clés communes correspondant à des mots de passe non salés sont utilisées à cet effet. Ils sont appelés « tables arc-en-ciel ».

Un autre écueil lors de la création d’un sel est d’utiliser une fonction de génération de nombres aléatoires qui n’a pas été conçue pour la sécurité. Un exemple est le rand() fonction en C, accessible depuis Swift. Cette sortie peut finir par être très prévisible!

Pour créer un sel sécurisé, nous utiliserons la fonction SecRandomCopyBytes pour créer des octets aléatoires cryptographiquement sécurisés, c’est-à-dire des nombres difficiles à prévoir.

Pour utiliser le code, vous devrez ajouter ce qui suit dans votre en-tête de pontage:
#import <CommonCrypto/CommonCrypto.h>

Voici le début du code qui crée un sel. Nous ajouterons à ce code au fur et à mesure:

Nous sommes maintenant prêts à faire des étirements clés. Heureusement, nous avons déjà une fonction à notre disposition pour faire l’étirement proprement dit: la fonction de dérivation de clé basée sur un mot de passe (PBKDF2). PBKDF2 exécute une fonction plusieurs fois pour dériver la clé; l’augmentation du nombre d’itérations augmente le temps nécessaire pour opérer sur un ensemble de clés lors d’une attaque par force brute. Il est recommandé d’utiliser PBKDF2 pour générer votre clé.

Clé côté serveur

Vous vous interrogez peut-être maintenant sur les cas où vous ne souhaitez pas obliger les utilisateurs à fournir un mot de passe dans votre application. Peut-être qu’ils s’authentifient déjà avec un système d’authentification unique. Dans ce cas, demandez à votre serveur de générer une clé AES 256 bits (32 octets) à l’aide d’un générateur sécurisé. La clé doit être différente pour différents utilisateurs ou appareils. Lors de l’authentification auprès de votre serveur, vous pouvez transmettre au serveur un identifiant d’appareil ou d’utilisateur via une connexion sécurisée et il peut renvoyer la clé correspondante.

Ce schéma a une différence majeure. Si la clé provient du serveur, l’entité qui contrôle ce serveur a la capacité de lire les données chiffrées si l’appareil ou les données ont déjà été obtenus. Il est également possible que la clé soit divulguée ou exposée ultérieurement.

D’un autre côté, si la clé est dérivée de quelque chose que seul l’utilisateur connaît – le mot de passe de l’utilisateur – alors seul l’utilisateur peut déchiffrer ces données. Si vous protégez des informations telles que des données financières privées, seul l’utilisateur devrait être en mesure de déverrouiller les données. Si ces informations sont de toute façon connues de l’entité, il peut être acceptable que le serveur déverrouille le contenu via une clé côté serveur.

Modes et IV

Maintenant que nous avons une clé, chiffrons certaines données. Il existe différents modes de chiffrement, mais nous utiliserons le mode recommandé: le chaînage de blocs de chiffrement (CBC). Cela fonctionne sur nos données un bloc à la fois.

Un écueil courant avec CBC est le fait que chaque bloc de données non chiffré suivant est XOR‘d avec le bloc crypté précédent pour rendre le cryptage plus fort. Le problème ici est que le premier bloc n’est jamais aussi unique que tous les autres. Si un message à chiffrer devait commencer de la même manière qu’un autre message à chiffrer, la sortie chiffrée de début serait la même, ce qui donnerait à un attaquant un indice pour déterminer ce que le message pourrait être.

Pour contourner cette faiblesse potentielle, nous allons commencer la sauvegarde des données avec ce qu’on appelle un vecteur d’initialisation (IV): un bloc d’octets aléatoires. Le IV sera XOR avec le premier bloc de données utilisateur, et comme chaque bloc dépend de tous les blocs traités jusqu’à ce point, il garantira que tout le message sera crypté de manière unique, même s’il a les mêmes données qu’un autre message. En d’autres termes, des messages identiques chiffrés avec la même clé ne produiront pas de résultats identiques. Ainsi, bien que les sels et les intraveineuses soient considérés comme publics, ils ne devraient pas être séquentiels ou réutilisés.

Nous utiliserons le même sécurisé SecRandomCopyBytes fonction pour créer le IV.

Mettre tous ensemble

Pour compléter notre exemple, nous utiliserons le CCCrypt fonction avec soit kCCEncrypt ou kCCDecrypt. Parce que nous utilisons un chiffrement par bloc, si le message ne rentre pas bien dans un multiple de la taille du bloc, nous devrons dire à la fonction d’ajouter automatiquement un remplissage à la fin.

Comme d’habitude dans le cryptage, il est préférable de suivre les normes établies. Dans ce cas, la norme PKCS7 définit comment remplir les données. Nous demandons à notre fonction de cryptage d’utiliser cette norme en fournissant le KCCOptionPKCS7Padding option. En rassemblant le tout, voici le code complet pour crypter et décrypter une chaîne.

Et voici le code de décryptage:

Enfin, voici un test pour vous assurer que les données sont correctement décryptées après le cryptage:

Dans notre exemple, nous emballons toutes les informations nécessaires et les renvoyons sous forme de Dictionary afin que toutes les pièces puissent être utilisées plus tard pour décrypter avec succès les données. Il vous suffit de stocker l’IV et le sel, soit dans le trousseau, soit sur votre serveur.

Conclusion

Ceci complète la série en trois parties sur la sécurisation des données au repos. Nous avons vu comment stocker correctement les mots de passe, les informations sensibles et de grandes quantités de données utilisateur. Ces techniques constituent la base de la protection des informations utilisateur stockées dans votre application.

C’est un risque énorme lorsque l’appareil d’un utilisateur est perdu ou volé, en particulier avec des exploits récents pour accéder à un appareil verrouillé. Alors que de nombreuses vulnérabilités du système sont corrigées avec une mise à jour logicielle, l’appareil lui-même n’est aussi sécurisé que le code d’accès de l’utilisateur et la version d’iOS. Par conséquent, il appartient au développeur de chaque application de fournir une protection renforcée des données sensibles stockées.

Tous les sujets abordés jusqu’à présent utilisent les frameworks d’Apple. Je vais vous laisser une idée sur laquelle réfléchir. Que se passe-t-il lorsque la bibliothèque de chiffrement d’Apple est attaquée?

Lorsqu’une architecture de sécurité couramment utilisée est compromise, toutes les applications qui en dépendent sont également compromises. Toutes les bibliothèques liées dynamiquement à iOS, en particulier sur les appareils jailbreakés, peuvent être corrigées et échangées avec des bibliothèques malveillantes.

Cependant, une bibliothèque statique fournie avec le binaire de votre application est protégée contre ce type d’attaque, car si vous essayez de la corriger, vous finissez par changer le binaire de l’application. Cela cassera la signature de code de l’application, l’empêchant de se lancer. Si vous avez importé et utilisé, par exemple, OpenSSL pour votre chiffrement, votre application ne serait pas vulnérable à une attaque d’API Apple généralisée. Vous pouvez compiler OpenSSL vous-même et le lier statiquement à votre application.

Il y a donc toujours plus à apprendre et l’avenir de la sécurité des applications sur iOS est en constante évolution. L’architecture de sécurité iOS prend même désormais en charge les dispositifs cryptographiques et les cartes à puce! En terminant, vous connaissez désormais les bonnes pratiques pour sécuriser les données au repos, c’est donc à vous de les suivre!

En attendant, consultez certains de nos autres contenus sur le développement d’applications iOS et la sécurité des applications.

Soutenez notre effort ❤️

Si vous avez apprécié cet article, pensez à laisser un pourboire pour nous aider à continuer à publier du contenu de qualité.

Paiement sécurisé sur PayPal
Moyens I/O Staff est une équipe de rédacteurs spécialisés, passionnés par la technologie, l’innovation et les usages numériques. Forts d’une expertise pointue en IA, applications mobiles, gaming et tendances digitales, nous produisons un contenu rigoureux, vérifié et utile. Notre mission : vous offrir une information fiable et claire pour mieux naviguer dans le monde numérique en constante évolution. Découvrez les avis de nos lecteurs sur Trustpilot.