Comment fonctionne la cryptographie ?

La cryptographie, ce n’est pas seulement une chose numérique

Comme le définit Bruce Schneier dans son livre Applied Cryptography, « L’art et la science de garder les messages en sécurité est la cryptographie (…) ». La cryptographie, bien qu’elle soit maintenant considérée comme fondamentale dans notre vie numérique, n’est pas spécifiquement liée à l’informatique. Elle existe sous diverses formes depuis des millénaires. Extrait de l’article de

Vous avez probablement déjà vu des exemples simples de cryptographie. Un chiffre César, ou chiffre à décalage, est couramment utilisé dans les jeux pour enfants qui impliquent le décodage d’un message secret. ROT13 est un type extrêmement courant de chiffrement à décalage dans lequel l’alphabet est tourné de 13 pas, comme illustré ci-dessous :
ROT13 en action. (Wikimedia Commons)

Il est facile de voir que ce type de chiffrement n’offre aucune sécurité réelle, mais c’est une illustration simple et amusante de l’idée générale derrière la cryptographie.

De nos jours, quand on parle de cryptographie, on en parle habituellement dans le contexte de la technologie. Comment les renseignements personnels et financiers sont-ils transmis en toute sécurité (ce qu’on appelle la protection des données en transit) sur le Web, disons, lorsque nous faisons un achat ou que nous consultons nos comptes bancaires ? Comment les données peuvent-elles être stockées en toute sécurité (ce qu’on appelle la protection des données au repos) pour que quelqu’un ne puisse pas simplement ouvrir un ordinateur, extraire le disque dur et s’en donner à cœur joie avec les informations qu’il contient ?

Quelques définitions et une introduction rapide à la cybersécurité

Dans le domaine de la cybersécurité, il y a un certain nombre de choses qui nous préoccupent lorsqu’il s’agit de données. Il s’agit notamment de la confidentialité, de l’intégrité, de la disponibilité et de la non-répudiation.

La confidentialité signifie que nos données ne peuvent pas être consultées ou lues par des utilisateurs non autorisés.

L’intégrité signifie que nos données nous parviennent intactes à 100%, et n’ont pas été modifiées, que ce soit par un acteur malveillant, une perte de données ou autre.

La disponibilité signifie que nos données sont accessibles en cas de besoin.

La non-répudiation signifie que si Robert envoie des données à Marie, il ne devrait pas pouvoir prétendre plus tard qu’il n’était pas, en fait, l’expéditeur de cette information. En d’autres termes, il existe un moyen de déterminer que personne d’autre que Bob n’aurait pu envoyer les données.

La cryptographie ne fait pas grand-chose pour nous en termes de disponibilité, mais nous examinerons les différentes formes de cryptographie numérique et comment elles peuvent nous aider à atteindre les trois autres objectifs énumérés ci-dessus. Lorsque nous parlons de cryptographie numérique, nous faisons généralement référence à l’un des éléments suivants :

  • Cryptage symétrique
  • Cryptage asymétrique
  • Fonctions de hachage
  • Signatures numériques

Je développerai chacun de ces points ci-dessous. Tous les exemples de code sont adaptés de l’excellent post de Jesus Castello sur SitePoint, Exploring Cryptography Fundamentals in Ruby, ainsi que de la documentation officielle Ruby. N’oubliez pas non plus que ces exemples visent à illustrer les concepts et non à fournir des pratiques exemplaires en matière de sécurité des données.

Cryptage symétrique

D’accord, avant d’entrer dans le vif du sujet : qu’entend-on exactement par « cryptage » ? Le chiffrement et le déchiffrement sont généralement utilisés pour désigner respectivement le chiffrement et le déchiffrement ; en termes simples, chiffrer un message signifie le rendre illisible pour les personnes non autorisées en utilisant un chiffre (la méthode spécifique pour le faire). Décrypter le message signifie inverser le processus et rendre les données lisibles une fois de plus.

Pour crypter et décrypter correctement nos données, nous avons besoin à la fois des données et d’une clé (qui détermine la sortie de notre chiffre).

Avec le cryptage symétrique, la clé utilisée pour crypter et décrypter les données est la même. Prenons une chaîne de caractères et cryptons-la en utilisant Ruby et OpenSSL :

Notez que je fais cela de manière destructive (réassigner la variable qui contenait notre chaîne originale) afin de démontrer que nous cryptons et décryptons effectivement. Maintenant, passons à notre console Pry :

Notez que notre variable data_to_encrypt, qui était initialement fixée à’now you can read me!’, est maintenant un tas de déchets illisibles. Inversons le processus, en utilisant la clé que nous avons initialement sauvegardée dans la variable clé.

Comme nous pouvons le voir, en utilisant la même clé que nous avons définie pour le cryptage, nous récupérons notre chaîne originale.

Cryptage asymétrique

Le problème du cryptage symétrique est le suivant : Que faire si j’ai besoin d’envoyer des données en toute sécurité dans un environnement hostile, tel qu’Internet ? Si la même clé est utilisée pour crypter et décrypter les données, je dois d’abord vous envoyer la clé de décryptage pour établir une connexion sécurisée. Mais cela signifie que j’envoie la clé sur une connexion non sécurisée pour commencer, ce qui signifie que la clé peut être interceptée et utilisée par un tiers ! Comment pouvons-nous contourner ce problème ? Saisissez un cryptage asymétrique.

Je n’ai jamais vraiment étudié les mathématiques du chiffrement asymétrique, et cela dépasserait de toute façon la portée de ce billet de blog, mais je peux vous donner une idée générale. Pour utiliser un chiffre asymétrique, vous devez générer deux clés qui sont mathématiquement liées. Une clé est votre clé privée, à laquelle vous seul devriez avoir accès, et votre clé publique, qui (comme son nom l’indique) peut être partagée publiquement avec quiconque.

Ainsi, vous demandez une connexion sécurisée à un serveur, le serveur envoie sa clé publique, le client génère une clé pour un chiffrement symétrique et la chiffre avec la clé publique du serveur, le serveur décrypte le message contenant la clé symétrique avec sa clé privée, et maintenant que les deux parties ont la clé symétrique, une connexion sécurisée peut être établie avec un chiffrement symétrique.

Mais attendez ! Maintenant, nous avons un autre problème. Comment puis-je savoir si la clé publique du serveur est légitime, c’est-à-dire qu’elle appartient à ce serveur ? En général, il y a plusieurs façons de régler ce problème, mais la méthode la plus courante (et celle utilisée sur le Web) consiste à utiliser l’infrastructure à clé publique (ICP). Dans le cas des sites Web, il existe une autorité de certification qui possède un répertoire de tous les sites Web auxquels elle a délivré des certificats, ainsi que leurs clés publiques. Lorsque vous vous connectez à un site Web, sa clé publique est d’abord vérifiée auprès de l’autorité de certification.

Tout d’abord, notez que notre clé et notre clé publique sont des objets séparés avec des ID d’objet différents. En utilisant#private_encrypt, nous pouvons crypter notre chaîne en utilisant notre clé privée. Encore une fois, notez la sortie absurde que nous avons mise dans notre variable data_to_encrypt. Décryptons maintenant les données à l’aide de notre clé publique :
Ta-da !

En utilisant #public_decrypt, nous avons pu récupérer le message original en n’utilisant PAS la clé privée avec laquelle nous avons initialement crypté le message, mais sa clé publique associée. La même chose fonctionne à l’envers.

Fonctions de hachage

Une fonction de hachage, contrairement au cryptage symétrique/asymétrique, est une fonction unidirectionnelle. Vous pouvez créer un hachage à partir de certaines données, mais il n’y a aucun moyen d’inverser le processus. En tant que tel, ce n’est pas un moyen utile de stocker des données, mais c’est un moyen utile de vérifier l’intégrité de certaines données.

Une fonction de hachage prend certaines données en entrée et produit une chaîne apparemment aléatoire (mais pas du tout) qui sera toujours de la même longueur. Une fonction de hachage idéale crée des valeurs uniques pour différentes entrées. La même entrée produira toujours exactement le même hachage – c’est pourquoi nous pouvons l’utiliser pour vérifier l’intégrité des données.

Utilisons une nouvelle chaîne de caractères cette fois-ci, exécutons-la dans une fonction de hachage, et stockons ce hachage dans une variable.

Tout d’abord, hachons à nouveau notre chaîne et comparons ce résumé à celui que nous avons sauvegardé dans la variable digest.

Comme nous pouvons le voir, tant que les données restent les mêmes, les résumés correspondront toujours. Maintenant, changeons un peu les données et comparons les digests. Ensuite, nous changerons les données pour qu’elles redeviennent exactement ce qu’elles étaient à l’origine, et nous comparerons les digests une fois de plus.

Pour vous donner une idée de la façon dont les digests sont différents, même pour des données similaires, jetez un coup d’œil aux digests eux-mêmes :

Signatures numériques

Les signatures numériques sont parfaites tant pour l’intégrité que pour la non-répudiation. Une signature numérique est une combinaison de hachage et de cryptage asymétrique. C’est-à-dire qu’un message est d’abord haché, et ce hachage est chiffré avec la clé privée de l’expéditeur. Il s’agit de la signature, qui est envoyée avec le message.

Le destinataire utilise la clé publique de l’expéditeur pour extraire le hachage de la signature et le message est ensuite haché pour le comparer au hachage extrait. Si vous êtes sûr que la clé publique appartient à l’expéditeur et que le décryptage de la clé publique est réussi, vous pouvez être assuré que le message provient bien de l’expéditeur. Si le hachage extrait correspond au hachage calculé pour le message, vous pouvez être assuré de l’intégrité du message.

N’oubliez pas qu’une signature numérique ne rend pas nécessairement le message confidentiel ; il est absolument possible de signer un message en clair. Les signatures numériques fonctionnent avec les messages cryptés, mais le cryptage du message lui-même doit être effectué séparément.