La souveraineté dans le Cloud par le chiffrement tierce-partie – Partie 3

Temps de lecture : 10 minutes

Rappel des articles précédents :

Dans cet article, nous allons parler d’un des deux problèmes fondamentaux, et insolvables, que rencontre nécessairement toute solution de chiffrement tierce-partie telle que Sovereign Keys. En l’occurrence, le problème de l’interception des clés en transit.

Ceux d’entre vous qui ont une culture sécurité des réseaux sont peut-être en train de se dire : “Mais qu’est-ce qu’il a fumé le Jérémie ? Ca fait belle lurette qu’on a résolu le problème de la protection des données en transit et encore heureux pour notre mode de vie numérique moderne”. À cela je répondrai “oui.. Mais c’est plus compliqué que ça”. Explications.

Je vais commencer par rappeler quelques éléments cruciaux du fonctionnement de Sovereign Keys autour du sujet qui nous intéresse, puis je décrirai le problème et enfin les mitigations que nous avons mises en place.

Le secret à protéger

Nous avons vu dans le précédent article que Sovereign Keys (SK) avait une hiérarchie de clés, avec une Domain Key, une Customer Master Key et un Instance Secret. Deux schémas étaient utilisés pour l’explication, et l’un d’eux montrait où chaque secret réside. Sur ce schéma, on remarquait que l’Instance Secret est le seul secret qui peut exister en clair à la fois du côté “client” et du côté “Sovereign Keys” et que c’est le côté “client” qui stocke l’Encrypted Instance Secret :

Et si l’Instance Secret est présent en clair à la fois du côté SK et du côté client et que Sovereign Keys est le seul système à pouvoir récupérer l’Instance Secret à partir du Encrypted Instance Secret, alors, à un moment, il faut bien qu’il transite d’une façon ou d’une autre.

Effectivement, si on résume à l’extrême la cinématique de la demande de déchiffrement vue à la fin du précédent article, voici ce qui se passe :

La Customer Instance décline son identité à SK et transmet l’Encrypted Instance Secret à déchiffrer. SK vérifie l’identité de l’instance et s’assure que l’Encrypted Instance Secret lui appartient, et si tout va bien renvoie l’Instance Secret.

Nous verrons la vérification d’identité et d’appartenance de l’Instance Secret dans le prochain article. Pour l’instant, voyons comment ce secret est protégé en transit et quelles sont les limites de cette protection.

Le chiffrement de bout en bout du secret

Dans notre situation, on veut faire passer l’Encrypted Instance Secret de la Customer Instance aux HSMs, les seuls composants capables de le déchiffrer, puis l’Instance Secret obtenu des HSMs à la Customer Instance :

Mais si on fait ça aussi simplement, alors l’Instance Secret transite en clair du HSM cluster à la Customer Instance, ce qui est en général une mauvaise pratique. D’autant plus qu’il transite en clair sur le réseau de l’opérateur qui pourrait donc le voir (l’Encrypted Instance Secret est chiffré lui, donc aucun problème) :

Idéalement, on veut que l’Instance Secret soit protégé de bout en bout, c’est-à-dire qu’il soit complètement illisible entre le HSM cluster et la Customer instance. Une manière classique de réaliser cela, c’est de faire en sorte que les HSM chiffrent l’Instance Secret de sorte à ce que seule la Customer Instance puisse le déchiffrer. On parle de “chiffrement de bout en bout”. Comment fait-on ça avec Sovereign Keys (SK) ?

Pour SK, la Customer Instance génère à chaque demande une paire de clés RSA temporaire et envoie la Public RSA key aux HSMs. Ces derniers l’utilisent pour chiffrer l’Instance Secret. Ainsi, seul le détenteur de la Private RSA key peut le lire, à savoir la Customer Instance :

Et voilà, problème résolu ? Non, c’est oublier que le Cloud Provider a peut-être la possibilité de manipuler le flux réseau.

MITM !

On pourrait imaginer que le Cloud Provider change la Public RSA key en chemin et la remplace par sa propre Public RSA key. De fait, les HSM renverront un Instance Secret qu’il peut déchiffrer avec sa Private RSA key. Il peut ensuite garder l’Instance Secret et, pour rester discret, le renvoyer à la Customer Instance chiffré avec la Public RSA key d’origine.

C’est le problème du Man-In-The-Middle (MITM). Ce qui est affreux dans cette situation, c’est que vous pouvez vous convaincre que du point de vue de la Customer Instance, tout se passe normalement ; et du point de vue des HSMs, tout se passe normalement aussi. Pourtant l’Instance Secret a été compromis.

Pour éviter ça, les HSM signent cryptographiquement tout ce qu’ils produisent, de sorte que la Customer Instance peut toujours vérifier la provenance des informations. On avait déjà vu ça avec les logs dans la partie 1, et en réalité cela s’applique aussi aux Instance Secret (et à tout ce qu’envoie SK en général). De fait, notre MITM n’est pas capable de répondre à la Customer Instance, car il est incapable de produire une signature valide :

Notez tout de même que ça ne l’empêche pas de récupérer notre Instance Secret ; c’est donc peu satisfaisant. Peut-on faire mieux ? Pas vraiment.

SMITM !

Le problème, c’est que le Cloud Provider n’est pas seulement Man-In-The-Middle (MITM). C’est en fait Superman-In-The-Middle (SMITM) ! Il ne contrôle pas que le réseau mais aussi le matériel d’une des extrémités de la connexion (la Customer Instance). On peut donc supposer que non seulement il peut manipuler le réseau, mais également le volume de la Customer Instance. Et si on suppose ça, ça compromet le modèle de sécurité des solutions “classiques”. Prenons en deux à titre d’exemples.

Certifier la clé de la Customer Instance

Pour contrer le SMITM, on pourrait vouloir certifier la Public RSA key que la Customer Instance fournie aux HSMs. En effet, dès lors qu’on est sûr que c’est bien cette clé (et non une clé spoofée comme sur le schéma précédent) qui parvient aux HSMs, alors on a gagné. Certifier la Public RSA key permettrait aux HSMs de savoir s’il y a eu manipulation ou pas, et donc les HSMs ne libéreraient l’Instance Secret qu’après avoir vérifié qu’ils ont une Public RSA key authentique.

Pour faire cette certification, il existe plusieurs moyens techniques dont l’explication est hors du périmètre de cet article, mais dans tous les cas la paire de clés RSA doit devenir statique au lieu d’être générée à la demande pour chaque opération. Il faut donc stocker la Private RSA key de manière permanente. Hors, on parle ici d’une clé RSA qui sert à obtenir l’Instance Secret qui protège les volumes Sovereign Keys (SK). Cette clé privée ne peut donc pas être elle-même stockée dans un volume SK, il faut forcément la stocker dans un volume non protégé par SK. Or si nous sommes en train de parler de SK, c’est parce qu’on fait l’hypothèse que le Cloud Provider peut lire de tels volumes. Donc la paire de clés RSA ne peut pas être permanente, et donc on ne peut pas certifier la Public RSA key.

TLS

Sur Internet, quand un client se connecte à un serveur, ce dernier lui présente un certificat permettant à la fois de prouver qui il est et d’établir une connexion sécurisée de bout en bout : c’est le protocole TLS (Transport Layer Security), sur lequel repose HTTPS. Ne pourrait-on pas faire quelque chose de similaire ?

Ici le problème vient de la manière dont la Customer Instance va vérifier le “certificat”. Le principe général des certificats électroniques est de fonctionner par chaîne de confiance : un certificat est certifié par une autorité, qui a elle-même un certificat certifié par une autre autorité, etc… jusqu’à ce qu’on tombe sur un certificat qu’on connait déjà et en lequel on a ultimement confiance. Chaque ordinateur du monde possède une liste de ces certificats ultimes. Dans notre cas, la Customer Instance utiliserait donc sa propre liste de certificats ultimes pour vérifier le certificat de Sovereign Keys (SK). Bien entendu, la vérification est un prérequis à l’obtention de l’Instance Secret donc cette liste des doit être stockée dans un volume non protégé par SK. Or si nous sommes en train de parler de SK, c’est parce qu’on fait l’hypothèse que le Cloud Provider peut écrire de tels volumes, donc manipuler la liste des certificats, et donc fausser la vérification.

Notez que cette faiblesse existe aussi pour la vérification de la signature de l’Instance Secret dont on a parlé plus haut dans MITM ! et en général pour n’importe quelle signature vérifiée par la Customer Instance en autonomie.

Par contre, rassurez-vous, il n’y a pas de problème pour la vérification des signatures des logs car normalement elle est faîte par un système hors de portée du Cloud Provider (sauf si vous avez tout chez le Cloud Provider, dans ce cas on peut imaginer n’importe quoi). Les logs SK restent infalsifiables.

La traçabilité comme seule mitigation possible

Et au final, ce sont bien ces fameux logs infalsifiables qui permettent de détecter à coup sûr s’il y a eu, ou pas, compromission lors du transfert d’un Instance Secret. En effet, Sovereign Keys (SK) insert toujours dans ses logs la copie complète de la Public RSA key reçue de la part de la Customer Instance. Si vous collectez également les logs de la Customer Instance, qui contiennent eux aussi la Public RSA key, alors il suffit de vérifier que ce sont toujours les mêmes valeurs.

Conclusion préliminaire

Vous l’aurez compris, je suis explicitement en train de dire qu’en fin de compte on ne peut pas garantir à 100% la protection de l’Instance Secret durant son transit entre les HSM et la Customer Instance. Et encore, le pire est à venir (le fameux quatrième article). Est-ce que c’est grave ? Ça dépend de votre analyse de risque.

Si vous pensez que votre Cloud Provider vous en veut personnellement, souhaite voler vos données pour son propre compte et est prêt à tout pour ça ; alors aucune solution technique ne peut vous en prémunir et il ne faut simplement pas exécuter vos applications dans le Cloud. Il faut bien comprendre que votre Cloud Provider possède l’infrastructure et donc si vous doutez de tout ce qu’il vous présente (la documentation, les garanties contractuelles, les certifications tierces, …) vous pouvez imaginer absolument n’importe quoi. Peut-être qu’il a posé des chipsets espions sur tous les BUS de cartes-mères de ses serveurs, ou qu’il peut “voir” tout ce qui se passe dans un processeur parce qu’il est en permanence observé par microscopie électronique, qu’en savez vous ?

Si vous pensez que votre Cloud Provider n’a pas d’intérêt personnel à voler vos données, mais pourrait être contraint par un tiers (au hasard, un Etat, par exemple) à les divulguer ; alors ce qui compte n’est pas de rendre complètement impossible l’accès à vos données par le Cloud Provider, mais plutôt d’empêcher qu’il puisse être contraint à le faire.

Et dans ce cas, un système de chiffrement tierce partie quelconque est efficace : votre Cloud Provider peut toujours se dédouaner en disant qu’il n’a pas accès aux clés de chiffrement. Et c’est vrai ! Les attaques potentielles que j’évoque dans cet article sont complètement irréalistes dans un fonctionnement normal des services, elles nécessiteraient des semaines ou des mois de préparation, d’observation, pour se synchroniser et lancer une attaque qui sera de toute façon détectable et dont il faudra s’expliquer. Et c’est dans cet esprit que Sovereign Keys est né : donner un moyen supplémentaire au Cloud Provider pour se protéger d’injonctions extérieures.

Maintenant que ce disclaimer est fait, nous sommes prêts pour le prochain et dernier article. Nous y parlerons de l’ultime problème qui interdit tout espoir d’une solution technique parfaite : l’authentification. Et vous verrez, c’est frappant.

Commentaires :

A lire également sur le sujet :