Points Clés
- La cryptographie dans la couche application fait partie d'une tendance à déplacer davantage d'infrastructures et de responsabilités informatiques vers des rôles de développeur ou de DevOps.
- Le chiffrement de bout en bout est un type de cryptographie dans la couche application de plus en plus populaire.
- Ce type de chiffrement permet aux organisations d'appliquer le contrôle d'accès à l'aide de la gestion des clés ainsi que des politiques.
- La livraison de code en toute sécurité aux utilisateurs finaux est très différente selon la plate-forme; celui basé sur JavaScript dans un navigateur est le plus difficile.
- La confidentialité et la sécurité peuvent être grandement améliorées avec ces approches, donc malgré les défis, cela en vaut la peine.
Quiconque manipule des données utilisateur sensibles vit dans la peur d'une violation de données. Nous savons que le chiffrement peut réduire les conséquences négatives, mais la plupart du chiffrement est relégué aux éléments de niveau infrastructure comme TLS et VPN plutôt qu'à la couche application. Le chiffrement dans la couche application et de bout en bout peut être un outil puissant dans notre boîte à outils, mais en tant que développeurs, comment pouvons-nous ajouter en toute sécurité le chiffrement à nos applications sans introduire de bogues ou réduire l'utilité des données ?
Dans cet article, nous discutons des avantages et des inconvénients du chiffrement dans la couche application. Nous couvrirons la surface d'attaque du chiffrement dans la couche application d'un navigateur, en quoi il est très différent des clients natifs et comment WebCrypto aide.
Le paysage des menaces
La réputation, l'impact financier et humain des brèches peuvent être extrêmement élevés. De nouvelles lois qui aident à protéger la vie privée des utilisateurs finaux constituent un pas en avant important, mais elles s'accompagnent d'amendes potentiellement ruineuses.
Des études montrent que le chiffrement est l'une des mesures de sécurité technique les plus efficaces pour réduire l'impact et le coût d'une violation de données. Lorsque les attaquants obtiennent des ensembles de données chiffrés, ils doivent soit attaquer un autre système pour obtenir la clé, soit se contenter de métadonnées et d'informations sur les canaux latéraux au lieu de «ce qui est utile».
Le chiffrement est généralement axé sur les éléments de la «couche infrastructure», tels que TLS, les VPN, le chiffrement des bases de données et le chiffrement complet de disques. Ce sont des outils importants dans notre boîte à outils, mais ils reposent sur des hypothèses concernant l'infrastructure au lieu du code de l'application lui-même.
En fait, si vous considérez les brèches de données les plus récentes, au moins parmi les entreprises établies, elles utilisaient certainement TLS et le chiffrement de base de données, et pourtant les fuites se sont quand même produites. Par exemple, Capital One a récemment été piraté et des informations financières sensibles ont été volées. Google Photos a accidentellement donné le mauvais accès aux utilisateurs aux photos et vidéos d'autres utilisateurs. Ces erreurs auraient pu être évitées, ou du moins atténuées, par le chiffrement dans la couche application de bout en bout.
En tant que développeurs, l'infrastructure n'est pas notre force, et parfois ce n'est pas notre travail, donc le chiffrement prend le pas sur les fonctionnalités. Mais pour ceux d'entre nous qui se soucient de la défense en profondeur, il est judicieux d'ajouter un chiffrement à l'application elle-même. Le chiffrement dans la couche application peut isoler nos systèmes des défaillances au niveau de l'infrastructure, des faiblesses connues de TLS et de certaines vulnérabilités côté serveur.
Le chiffrement en amont (Shift-Left Cryptography) : qu'est-ce que le chiffrement dans la couche application ?
La pratique consistant à transférer davantage de sécurité, d'opérations et de tests dans le processus de développement (appelé shift-left) améliore l'agilité, la fiabilité et l'efficacité des logiciels. Cela signifie également que les meilleures pratiques de sécurité doivent être mises en œuvre dans le cadre du développement d'applications, et non après coup lorsque les choses tournent mal. Cependant, la grande majorité des développeurs ne sont pas des experts en sécurité ou en cryptographie, et en même temps, l'équipe de sécurité a moins de contrôle sur la posture de sécurité de l'informatique et du développement que jamais auparavant.
Le chiffrement dand la couche application, ou la cryptographie shift-left, fait partie de cette tendance. Cela signifie donner aux développeurs plus de contrôle sur ce qui est chiffré et qui obtient les clés de déchiffrement. Dans certains cas, les utilisateurs eux-mêmes peuvent être les seuls à disposer des clés. Dans d'autres cas, le chiffrement dans la couche application peut être une couche de contrôle d'accès supplémentaire sur la gestion des données, offrant une défense en profondeur.
Comme l'indique le nom, le chiffrement dans la couche d'application est ajouté directement à la base de code de votre application, et l'accès à la clé est contrôlé par la logique de votre application. Par conséquent, vous pouvez penser que les données elles-mêmes sont chiffrées tout au long de leur cycle de vie, plutôt que de compter qu'elles se trouvent sur un réseau ou un disque chiffré.
Le chiffrement dans la couche application le plus largement compris est le chat chiffré de bout en bout comme Signal et WhatsApp fournissent, alors réfléchissons au fonctionnement de ces applications. C'est un peu trop simplifié, mais cela fonctionne essentiellement comme ceci :
Action de l'utilisateur final |
Logique de contrôle d'accès (serveur) |
Opération cryptographique dans la couche d'application (client) |
Ajouter un ami |
Créer une règle de contrôle d'accès dans laquelle les utilisateurs sont autorisés à s'envoyer des messages |
Faire confiance à la clé cryptographique de l'ami |
Écrire un message à l'ami |
Créer une règle de contrôle d'accès où l'ami peut lire le message |
Chiffrer le message avec la clé de votre ami (et le signer) |
Lire un message d'un ami |
Vérifier l'autorisation de télécharger le message |
Déchiffrer un message avec la clé de l'utilisateur final (et vérifier la signature) |
Dans cet exemple simple, nous pouvons déjà voir une partie de la puissance du chiffrement dans la couche application :
- L'utilisateur pense en termes de qui il veut parler, non pas de contrôle d'accès ou de chiffrement, mais en fait, l'utilisateur prend des décisions politiques.
- La logique de contrôle d'accès est appliquée avec la cryptographie (et définie qui a les clés), pas seulement les règles sur un serveur qu'un attaquant pourrait contourner.
- Le serveur n'a pas accès aux données en texte brut. Les attaques contre le serveur, telles que l'injection SQL, les menaces internes et les compromis au niveau racine (root-level compromise), ne peuvent pas révéler les données.
Notez qu'il s'agit d'un exemple de chiffrement de bout en bout, mais que tout le chiffrement dans la couche application n'est pas de bout en bout. En outre, des applications comme celles-ci ont toujours besoin de TLS et d'un autre chiffrement dans la couche infrastructure pour appliquer des éléments tels que l'authentification, empêcher les attaques de type replay et résoudre une foule d'autres problèmes.
Pourquoi TLS n'est pas suffisant
Lorsque nous pensons à TLS, nous imaginons que les données sont chiffrées à la source et déchiffrées sur le serveur. Mais cette simplification excessive cache les limites pratiques de TLS.
La réalité du chiffrement en transit laisse de côté le chiffrement des données inutilisées, ce qui a un impact sur la sécurité des deux extrémités de la transmission. Il ignore également complètement ce qui arrive aux données après la terminaison HTTPS, qui peuvent être plus éloignées du bord de votre réseau que vous le savez; à votre load balancer par exemple.
Qu'en est-il du chiffrement à d'autres points de l'application ? Si vous faites un travail de cryptographie supérieur à la moyenne, vous avez écrit du code robuste et bien testé dans votre application pour chiffrer les données inactives, vous avez utilisé HTTPS et IPSec sur votre réseau et vous avez activé le chiffrement transparent sur la base de données.
Avec cette approche, nous «chiffrons presque partout», mais à mesure que les données transitent dans le système, elles sont déchiffrées et rechiffrées à chaque étape. Chaque point qui touche des données en texte brut est une vulnérabilité potentielle, entraînant une grande surface d'attaque, et vous devez vous demander : «Pourquoi diable ces services intermédiaires ont-ils quand même besoin des données en texte brut ?» Ils ne le font probablement pas.
Le chiffrement dans la couche infrastructure se prête également à des failles de sécurité car des parties imprévues de l'infrastructure peuvent obtenir les données. Par exemple, vos sauvegardes de base de données et de disque peuvent ne pas être chiffrées, même si votre base de données l'est. Ou votre système de surveillance de l'état de santé peut consigner des données sensibles en texte brut et (horreur des horreurs) peut-être même les envoyer à un tiers. Ces lacunes de sécurité se produisent parce que différents individus ou services sont responsables de la sécurité à ces différents points :
- Côté mobile, votre équipe de développement ou votre fournisseur a dû écrire du code (ou au moins implémenter HTTPS correctement). Ou votre système de gestion des appareils mobiles (Mobile Device Management MDM) encapsule les données, ou peut-être que vous comptez sur l'utilisateur pour cocher la case "crypter le téléphone" et le fournisseur du système d'exploitation pour faire quelque chose de raisonnable pour cela.
- Dans le réseau, le service informatique ou DevOps est responsable du provisionnement des certificats et de la bonne configuration de HTTPS, ce qui n'est pas toujours aussi simple.
- Sur votre serveur, vous comptez sur l'informatique et les DevOps pour sécuriser l'accès interne à vos systèmes, et vous comptez sur le fournisseur cloud et le fournisseur de base de données pour implémenter la cryptographie transparente dans la base de données.
Chacune de ces solutions utilise des chiffrements, des bibliothèques et des tailles de clé différents. Vous comptez sur beaucoup de gens pour bien faire les choses. C'est un problème.
Fournir un code fiable
Le chiffrement concerne la communication; les données sont écrites et chiffrées par une partie, puis reçues et déchiffrées par une autre partie. L'expéditeur et le destinataire doivent tous deux avoir une application qui sait comment effectuer le chiffrement et le déchiffrement, et peuvent être approuvés pour le faire correctement. Mais c'est plus facile à dire qu'à faire.
Que faire si le code de chiffrement est malveillant ? Que pourrait faire un attaquant ? L'attaque la plus simple serait que l'application fonctionne exactement comme prévu, mais envoie également les messages non chiffrés aux méchants. Des attaques plus subtiles sont bien sûr possibles; ajouter des vulnérabilités cachées pour affaiblir le chiffrement, jouer avec les clés publiques, etc. Mais elles reviennent toutes à la même chose : un peu de code qui aide le méchant à obtenir le message secret.
Parlons donc de la livraison du code. Pour deux personnes communiquant à l'aide d'applications sur leurs téléphones mobiles, la chaîne de confiance se présente comme suit : un bon programmeur écrit un bon code de chiffrement, le compile dans une application, signe l'application avec une signature numérique et la télécharge dans un store d'applications via TLS. L'utilisateur télécharge une application avec TLS, le système d'exploitation vérifie si la signature numérique est «approuvée» et l'utilisateur exécute l'application pour avoir sa communication chiffrée. Notez que ce protocole est lui-même un échange de données cryptographiques dans la couche application. Des systèmes Linux comme Debian ont des protocoles similaires pour l'installation et la mise à niveau des applications serveur et de bureau.
Il y a un certain nombre de choses qui peuvent mal tourner avec le téléchargement de l'application fiable : l'utilisateur peut télécharger une version malveillante de l'application. Le fournisseur du système d'exploitation pourrait saper le contrôle de la signature numérique sur l'application. Un attaquant pourrait inciter l'utilisateur à installer une ancienne version vulnérable de l'application (ou à ne pas la mettre à niveau). N'importe lequel de ces types d'attaques rendrait suspecte la communication chiffrée de bout en bout. Mais pour la plupart, cela fonctionne bien.
La cryptographie au niveau de l'application est généralement implémentée dans du code natif exécuté sur des mobiles, des ordinateurs portables ou des serveurs, et peut utiliser un protocole comme celui-ci pour fournir un code fiable. Mais les applications modernes ont très souvent un composant majeur basé sur un navigateur, même pour les informations sensibles.
Et concernant le Web ?
Le modèle de livraison de code sur le Web est très différent d'une application. Lorsque les utilisateurs décident qu'ils souhaitent avoir une conversation sécurisée, ils visitent une page Web. Le navigateur télécharge du JavaScript à la demande via TLS. Au-delà d'avertir l'utilisateur des mauvaises connexions TLS, c'est la fin du protocole standard pour la livraison de code. Il repose entièrement sur TLS. Le JavaScript qui est livré doit effectuer le chiffrement dans la couche application et ne pas avoir de code malveillant qui envoie simplement le texte non chiffré aux méchants.
Pourquoi c'est un problème ? Disons par exemple que notre revendication de sécurité est que les données sont chiffrées dans un navigateur, déchiffrées dans un autre navigateur, et le serveur Web entre les deux ne peut pas voir les données sans que des avertissement et des voyants clignotants ne se déclenchent. Pour saper cette affirmation, le serveur doit simplement fournir un code JavaScript malveillant au moment du démarrage de l'application. Ainsi, un attaquant qui peut contrôler le serveur qui fournit le code ou divers aspects de DNS et TLS pourrait réussir cette attaque sans casser aucune crypto. Le code ne peut être envoyé qu'à une cible spécifique, ce qui le rend difficile à détecter pour les chercheurs en sécurité.
En fait, avec la vitesse des mises à jour des applications et de l'intégration continue, des attaques similaires sont possibles contre les applications mobiles et les ordinateurs de bureau. De nombreuses applications modernes utilisent des techniques de code dynamique pour fournir au moins du code à une application en temps réel; de nombreuses applications de bureau mettent à jour leur propre code à volonté. Cela donne aux attaquants la possibilité de détourner les mises à jour de code à divers points, mais également aux équipes de sécurité de patcher rapidement. Cela dit, les attaques par navigateur sont beaucoup mieux comprises.
Certaines personnes de la communauté de la sécurité et de la cryptographie soulignent ce problème pour dire que vous ne devriez pas faire de chiffrement basé sur un navigateur, ou si vous le faites, vous ne pouvez pas prétendre qu'il est sécurisé de bout en bout. Ou à tout le moins, que cela crée un faux sentiment de sécurité. Nous ne sommes pas d'accord. Il y a en effet des faiblesses, mais en tant que développeurs, nous devrions le faire de toute façon, car, en termes simples, les gens utilisent le Web à des fins critiques pour la sécurité.
Pourquoi le chiffrement dans la couche application dans le navigateur reste une bonne sécurité
Malgré le problème de livraison de code, le chiffrement dans la couche application dans le navigateur améliore considérablement la sécurité globale de tout système. La raison en est que la sécurité n'est pas tout ou rien. Très rarement, dans une infrastructure de serveur moderne, un seul navigateur ne parle qu'à un seul serveur Web qui exécute toutes les tâches; les systèmes modernes sont juste plus complexes que cela.
Par exemple, supposons que votre application Web utilise HTTPS et effectue un chiffrement de bout en bout basé sur un navigateur, mais qu'elle présente une vulnérabilité d'injection SQL. La nature de cette vulnérabilité est que l'attaquant trompe l'application pour inciter la base de données à vider les données sensibles (via HTTPS, ironiquement). Mais dans notre exemple, les données sont chiffrées de bout en bout, de sorte que la base de données ne contient que des messages chiffrés. Sans chiffrement de la couche application, le méchant obtiendrait quelque chose de beaucoup plus sensible : les messages en texte brut. Notez qu'avec cette vulnérabilité seule, l'attaquant ne peut pas modifier le code pour injecter du JavaScript malveillant; le code de chiffrement basé sur un navigateur est toujours valide.
D'un autre côté, si l'attaquant utilise un exploit d'exécution de code à distance sur le serveur d'API et peut modifier le JavaScript ou y injecter du code malveillant à la volée, ils peuvent saper le chiffrement de bout en bout, là encore en ajoutant simplement du code qui envoie les données en texte brut.
Ce ne sont que deux exemples, l'un où le chiffrement dans la couche application peut être compromis et l'autre où il ne le peut pas, mais il existe d'innombrables autres attaques qui peuvent être évitées avec un chiffrement de bout en bout : peut-être que vous avez un employé trop curieux qui cherche des informations privées sur des célébrités, mais qui n'ont pas accès au code. Vous avez peut-être sauvegardé votre base de données Postgres dans un bucket S3 et l'avez accidentellement laissée ouvert sur le Web. Peut-être qu'un attaquant peut affaiblir TLS, mais il n'agit que de manière passive; ils peuvent espionner mais ils ne peuvent pas faire d'injection de code.
Comme nous pouvons le voir, le chiffrement dans la couche application dans le navigateur offre une défense en profondeur, même s'il y a des défis à la livraison de code. Dans la section suivante, nous parlerons des approches qui atténuent ces défis.
Amélioration de la livraison de code de confiance au navigateur
Il existe plusieurs façons d'améliorer la sécurité du chiffrement dans la couche application dans le navigateur. La première ligne de défense consiste à utiliser un code bien écrit et fiable. Le développement d'applications modernes est beaucoup plus rapide car nous réutilisons une grande partie du code que nous trouvons sur le Web, mais si l'un des codes qui s'exécutent dans le navigateur de l'utilisateur est malveillant ou vulnérable, il compromet considérablement le chiffrement.
La protection du serveur qui fournit le code est également essentielle. Utilisez le principe du moindre privilège lors de l'attribution des droits de contrôle d'accès sur ce serveur. Utilisez le contrôle multipartite pour l'administration et le déploiement de code. Cela réduira considérablement le risque d'attaques internes.
Il existe également des paramètres de livraison de code sous-utilisés qui demandent au navigateur de prendre des précautions supplémentaires. Ce ne sont pas les valeurs par défaut car elles réduisent quelque peu la flexibilité du processus de développement et d'intégration, mais la sécurité qu'elles offrent vaut le coup, que votre application effectue ou non le chiffrement :
- HTTP Strict Transport Security (HSTS) : demande au navigateur de toujours charger cette page sur HTTPS. Cela empêche les attaques de rétrogradation, par exemple, si l'attaquant peut rediriger votre DNS vers un service malveillant, il ne peut pas rétrograder la connexion vers HTTP non chiffré.
- Strict Content Security Policies (CSP) : liste blanche de sources sûres pour le chargement de code. Dans le monde complexe du JavaScript moderne, cela empêche l'application de charger dynamiquement du code à partir d'une ressource distante que vous ne connaissez pas.
- Subresource Integrity (SRI) : ne chargez que les scripts auxquels vous savez que vous pouvez faire confiance. Cela utilise des hachages cryptographiques pour marquer les scripts approuvés. Si un attaquant modifie le JavaScript de chiffrement d'une application, cela modifiera le hachage et le code ne se chargera pas.
De plus, il existe une API du navigateur relativement nouvelle qui permet une fourniture efficace et sécurisée des primitives cryptographiques. L'API WebCrypto fournit des chiffrements, des hachages et d'autres composants de chiffrement de bas niveau. Cela est utile car vous n'avez pas à inclure ces algorithmes de chiffrement dans votre JavaScript. Le navigateur les implémente directement et peut profiter de l'exécution native locale et même de l'accélération matérielle. Cela n'empêche pas certaines attaques, comme l'envoi d'une copie non chiffrée des données aux méchants, mais WebCrypto rend le chiffrement basé sur navigateur plus standard et accessible.
D'autres pièges
La livraison de code sécurisé n'est pas le seul défi pour la mise en œuvre du chiffrement dans la couche application. Le plus gros problème est que la plupart des bibliothèques de chiffrement sont relativement difficiles à utiliser en toute sécurité et difficiles à implémenter de manière cohérente dans différents langages de programmation et plates-formes. Lorsque vous chiffrez quelque chose dans un navigateur et le déchiffrez dans une application, vous avez probablement besoin de trois implémentations différentes dans différentes langues (Android, iOS et JavaScript) qui utilisent toutes exactement les mêmes algorithmes de chiffrement et modes.
Le fonctionnement sécurisé de ces modes n'est pas très facile à comprendre. Par exemple, le chiffrement bien-aimé AES est sécurisé, mais le coupler avec un mode non sécurisé comme ECB (le mode par défaut en Java) n'est pas sécurisé. L'association d'AES avec GCM est considérée comme une meilleure pratique, mais même GCM a ses défauts; si vous chiffrez trop de données avec la même clé, ou si vous faites une erreur avec le vecteur/nonce d'initialisation, vous pourriez réellement divulguer du matériel de la clé, ce qui est un défaut que certains autres modes n'ont pas.
Une erreur peut rendre vos données chiffrées irrécupérables, ou pire encore, récupérables par un méchant.
Un autre défi est que si vous placez des données chiffrées dans votre base de données, elles ne sont plus aussi consultables. Vous devez planifier à l'avance les types de requêtes et de rétrogradations que vous voulez que la base de données fasse ou que vous voulez que votre application fasse. Si vous chiffrez l'adresse personnelle d'un utilisateur, par exemple, vous ne pouvez pas simplement faire un SELECT * pour toutes les lignes avec la chaîne "Oregon". Si la désélection par état fait partie du workflow de votre application, vous pouvez à la place de chiffrer l'adresse complète de l'utilisateur, mais ajouter un champ de métadonnées non chiffré avec son état afin que vous puissiez toujours effectuer cette requête. À partir de là, vous pouvez potentiellement utiliser la logique dans la couche application pour déchiffrer l'enregistrement et effectuer le reste de la recherche, mais la base de données ne sera pas d'une grande aide.
Les gens à qui je parle sont souvent préoccupés par les performances du chiffrement dans la couche application, mais ce n'est pas une préoccupation importante. Le chiffrement est rapide et le matériel est souvent accéléré de nos jours. Après tout, nous utilisons HTTPS pour diffuser des réseaux sociaux entiers avec des photos et des vidéos et nous ne remarquons pas vraiment de manque de performances. C'est similaire dans la couche application, et il est peu probable que le chiffrement soit un goulot d'étranglement.
Certes, il existe encore des attaques contre le chiffrement dans la couche application. Divers gouvernements ont rendu illégal ou juridiquement inutilisable l'exploitation d'un service de chiffrement ou l'installation d'une application chiffrée. Les utilisateurs qui sélectionnent des mots de passe faibles ou réutilisés peuvent saper complètement le chiffrement. Les utilisateurs oubliant les mots de passe sont également un défi à relever; que doit-il se passer dans ce cas ? L'utilisateur doit-il pouvoir récupérer ses données via un e-mail de réinitialisation de mot de passe ? Cela affaiblit lui-même l'argument du chiffrement de bout en bout.
Et bien sûr, une fois les données déchiffées, les attaquants peuvent attaquer le périphérique final lui-même. Cela est arrivé à WhatsApp en 2019, ce qui amène certains à se demander si le chiffrement de bout en bout est utile ou important. Mais le fait que les attaquants devaient cibler des individus spécifiques avec des attaques zero-day contre WhatsApp est une preuve suffisante pour moi que le chiffrement de bout en bout aide.
Comment réussir
Lors de la mise en œuvre du chiffrement dans votre application, vous devrez tenir compte de vos objectifs de sécurité spécifiques, de toutes les règles de conformité que vous pourriez avoir à suivre et des personnes dont vous avez besoin pour disposer de clés. La cryptographie est très spécifique à votre application. Un cryptographe qualifié peut vous aider à comprendre les forces et les faiblesses de votre approche, et aucun article de magazine ne peut vous dire ce qui est bien ou mal. Cependant, vous pouvez faire quelques choix qui vous rapprocheront d'une «bonne cryptographie», et vous pouvez souvent les utiliser en toute sécurité.
Commençons par un bref aperçu des trois principaux systèmes cryptographiques: symétrique, asymétrique et de hachage. Symétrique (clé partagée) est rapide et efficace, ces algorithmes sont généralement votre base de référence pour le chiffrement des données. AES est généralement ce que vous voulez. Le chiffrement symétrique souffre de difficultés avec la gestion des clés. Vous avez besoin d'un moyen d'obtenir la clé partagée pour les deux parties, c'est pourquoi vous avez besoin d'un chiffrement asymétrique. Les modes multi-blocs symétriques varient dans leurs propriétés de confidentialité et d'intégrité, et certains fonctionnent mieux avec différents types de données ou différentes contraintes système (comme l'absence d'un générateur de nombres aléatoires) : ECB, GCM, CBC, SIV, etc.
La cryptographie asymétrique (clé publique/privée) est plus lente et plus complexe que le cryptage symétrique, ces algorithmes sont généralement utilisés pour échanger des clés symétriques. RSA est le choix «classique» ici; ECC est plus moderne et efficace, et presque aussi largement pris en charge. En gros, les clés publiques sont utilisées pour crypter les données et vérifier les signatures. Les clés privées sont utilisées pour déchiffrer les données et générer des signatures.
Le hachage, les signatures cryptographiques et les codes d'authentification de message (message authentication codes MAC) assurent l'intégrité. Le hachage génère une chaîne courte qui prouve que les données sont inchangées ou, dans le cas des codes d'authentification de message, prouve que la personne détenant une clé secrète a «signé» les données. Beaucoup de gens pensent que le chiffrement implique l'intégrité, mais ce n'est pas le cas. Par exemple, AES ne fournit pas d'intégrité par défaut. Des algorithmes comme SHA2, Poly1305 et GCM aident.
La gestion des clés est un très gros sujet en soi, mais quelques points importants à considérer:
- Génération : les clés sont-elles aléatoires, de quelle taille sont-elles, symétriques ou asymétriques, etc.
- Stockage : faut-il dériver les clés d'un mot de passe généré par l'utilisateur ou les stocker pour une recherche ultérieure. En cas de stockage, avez-vous un endroit sûr pour les mettre comme un trousseau ou un module de sécurité matérielle (Hardware Security Module HSM) ? De nombreux systèmes d'exploitation et plates-formes prennent désormais en charge la gestion sécurisée des clés.
- Communication : Comment convenir d'une clé entre un client et un serveur ou deux utilisateurs. C'est très difficile avec des clés symétriques, mais aussi difficile pour les clés publiques. Les clés publiques n'ont pas besoin d'être secrètes, mais vous devez avoir confiance en ce qu'elles proviennent vraiment de la personne dont vous pensez qu'elles viennent. Pour cela, vous devez déjà avoir quelque chose en qui vous pouvez avoir confiance, ce qui peut être un problème de la poule et de l'oeuf.
Au-delà de la clé, il existe d'autres éléments de caractère aléatoire ou unique qui sont associés aux messages chiffrés. Le vecteur d'initialisation, le salt et les nonces entrent dans cette catégorie. Ceux-ci doivent également être communiqués à la partie de déchiffrement, ils doivent donc être stockés ou transmis. En règle générale, il est sûr de les transmettre non chiffrés avec le texte chiffré, mais vous devez faire attention de ne pas laisser l'attaquant les modifier.
Vous devez également remplir, encoder, sérialiser et signer vos messages. Croyez-le ou non, même un mauvais remplissage peut compromettre la confidentialité du message crypté. Pour signer des données structurées comme un objet JSON ou des en-têtes HTTP, vous avez besoin d'un moyen identique pour les deux parties de sérialiser et de désérialiser les données, sinon les signatures ne correspondront pas.
Si vous avez fait tout cela correctement, vous avez maintenant un message chiffré et signé. Il est probable qu'à ce stade, vous souhaiterez envoyer ce message à une autre partie, qui vérifiera la signature et déchiffrera le message. Cela signifie que vous devez communiquer tous vos choix : identifiant de clé, taille, chiffre, mode, IV, algorithme de hachage, etc. Cette communication elle-même est une faiblesse importante dans de nombreux systèmes de cryptographie. Par exemple, les attaquants ont réussi à inciter certains systèmes symétriques à se comporter comme des systèmes asymétriques et à envoyer leur clé partagée directement à l'attaquant. Oops.
Quelques recommandations que nous avons, en particulier si vous devez ou souhaitez vous en tenir aux algorithmes de chiffrements NIST/FIPS-140 qui sont parfois requis pour la conformité dans les travaux gouvernementaux ou bancaires :
- Cryptage symétrique: AES-GCM est un bon mode de fonctionnement car il offre une confidentialité multi-blocs (contrairement à ECC) et une authentification / intégrité (contrairement à CBC). Il est largement disponible, vous pouvez donc généralement compter sur sa présence lorsque vous en avez besoin. Cependant, vous devez être très prudent avec le nonce GCM, car la réutilisation du nonce (ou si l'attaquant peut le choisir) peut conduire à une fuite de clé. Ce n'est pas bon.
- Authentification : cela vérifie que la personne avec la clé privée a chiffré les données. Très important. Notre recommandation est la même que ci-dessus en utilisant la balise ajoutée par GCM.
- Échange de clés : Elliptic Curve Diffie-Hellman (ECDH) over curve P-384 est un bon choix.
- Hachage : SHA256 est assez standard de nos jours.
- N'utilisez pas de trucs anciens/cassés : Bien que cette liste ne soit pas exhaustive, les trucs «anciens ou cassés» les plus couramment utilisés incluent: DES, MD4, MD5, SHA1, RC4, AES-ECB (RSA est ancien, mais pas cassé. C'est bien de l'utiliser si c'est ce qui est disponible, mais préférez ECC si vous le pouvez.)
- libSodium : si vous n'avez pas besoin de la conformité NIST/FIPS, vous devriez certainement chercher dans libSodium. Il est très bien considéré et les bibliothèques sont généralement plus faciles à utiliser que les bibliothèques qui implémentent des chiffrements FIPS similaires.
Conclusion
Le chiffrement est un moyen exceptionnellement efficace de protéger les données, mais la plupart du chiffrement déployé aujourd'hui fait partie de l'infrastructure informatique et non des applications. En tant que développeurs, nous avons une opportunité unique d'améliorer la confidentialité et la sécurité de nos utilisateurs en faisant du chiffrement dans la couche application une partie de notre boîte à outils. Il y a certainement des défis à relever; les données chiffrées peuvent être plus difficiles à gérer, et la plupart des bibliothèques de chiffrement sont très difficiles à utiliser pour les développeurs non formés, mais l'avantage pour nos utilisateurs en vaut la peine !
Glossaire des termes
Ce qui suit n'est pas la définition officielle de ces termes, mais des commentaires en couleur pour vous aider à comprendre comment ces termes et technologies s'intègrent dans le chiffrement dans la couche application.
- Advanced Encryption Standard (AES) : l'une des normes de cryptage symétrique les plus courantes.
- Chiffrement asymétrique : également appelé cryptographie à clé publique. Plus lent, mais plus flexible en termes de gestion des clés que le cryptage symétrique. Les algorithmes incluent ECC et RSA. Généralement utilisé pour négocier des clés de chiffrement symétriques.
- Mode de chiffrement par bloc (Block Cipher Mode) : étant donné que les chiffrements symétriques comme AES ne gèrent qu'un nombre fixe de bits (par exemple 128), des méthodes sécurisées pour gérer plusieurs blocs doivent être utilisées. L'utilisation incorrecte de ces modes est une vulnérabilité courante. Les modes de bloc couramment utilisés sont GCM, ECB (bien qu'il ne soit pas sécurisé), CBC, SIV, entre autres.
- Domain Name System (DNS) : protocole d'identification des serveurs (généralement) en fonction de leur nom. DNS est un élément essentiel de l'infrastructure de sécurité, car le contrôle sur DNS peut permettre à un attaquant d'usurper l'identité d'un serveur auprès d'un utilisateur final.
- Algorithme de chiffrement FIPS 140/NIST: une collection d'algorithmes de chiffrement vérifiés par le gouvernement fédéral américain pour diverses utilisations. Certaines industries nécessitent l'utilisation de chiffrements et d'implémentations contrôlés. L'Institut national des normes et de la technologie (Institute of Standards and Technology NIST) les standardise.
- Modèle de sécurité matérielle (Hardware Security Model HSM) : boîtes à outils pour la gestion sécurisée des clés de chiffrement et des opérations. La couche matérielle offre une protection supplémentaire, par exemple contre les exploits privilégiés.
- Vecteur d'initialisation, salt et nonces : nombres aléatoires utilisés comme composants dans les algorithmes cryptographiques. Selon l'algorithme et le mode, chacun d'eux peut avoir des propriétés et des utilisations de sécurité différentes.
- Intégrité : propriété de sécurité selon laquelle une donnée ne peut pas être modifiée, ou si elle a été modifiée, que la modification peut être détectée ou la preuve qu'un message a été généré par une partie autorisée. Les MAC et les algorithmes comme SHA2, GCM et Poly1305 peuvent aider à fournir cette propriété.
- Chiffrement symétrique : algorithmes comme AES, où les deux parties utilisent la même clé pour le chiffrement et le déchiffrement. Plus rapide que le chifrement asymétrique, mais plus difficile de gérer les clés car la clé doit être échangée via un canal sécurisé.
- Transport Layer Security (TLS): norme répandue pour le chiffrement des communications «en transit». Parfois appelé HTTPS, mais également applicable à d'autres protocoles comme les VPN.
- Réseau privé virtuel (Virtual Private Network VPN): chiffrement des communications réseau. Il sécurise plus d'aspects du comportement des utilisateurs que le simple HTTPS et utilise souvent une technologie similaire.
A propos de l'auteur
Isaac Potoczny-Jonesest le fondateur et PDG de Tozny, LLC, une société de confidentialité et de sécurité spécialisée dans la gestion des identités et le chiffrement. Le travail d'Isaac dans le domaine de la cybersécurité couvre l'open source, le secteur public et les entreprises commerciales. Ses projets ont inclus le chiffrement de bout en bout pour la confidentialité dans la recherche sur des sujets humains, la collaboration sécurisée entre domaines, la gestion des identités, l'autorisation anonyme, l'authentification mobile sans mot de passe, l'anti-contrefaçon dans les appareils hardware et l'authentification préservant la confidentialité. Il a travaillé avec des agences comme la DARPA, la Marine, le Laboratoire de recherche de l'Air Force, le Département de la sécurité intérieure, le National Institute of Standards and Technologies et d'autres éléments du DoD et des communautés du renseignement. Isaac est un développeur open source actif dans les domaines de la cryptographie et des langages de programmation. Diplômes : Licence en informatique, maîtrise en cybersécurité