Francois Lesueur
3 years ago
3 changed files with 222 additions and 3 deletions
@ -0,0 +1,106 @@ |
|||
CM2 Cryptographie et sécurité des communications - Notes de cours |
|||
================================================================= |
|||
|
|||
|
|||
À la rencontre d'Alice, Bob et Ernest |
|||
===================================== |
|||
|
|||
Comment permettre à Alice et Bob de communiquer de manière *sûre* sur un canal *non sûr* ? |
|||
|
|||
* Alice et Bob veulent communiquer, Ernest écoute (attaque passive) ou altère (attaque active) les échanges |
|||
* Le medium non sûr : |
|||
* Un messager qui peut se faire capturer |
|||
* Un réseau de câbles téléphoniques |
|||
* Internet (routage multi-saut multi-acteurs, écoute possible sur la route + par des attaquants qui arriveraient à dévier) |
|||
* Exemples de positions *MitM - Man in the Middle* : |
|||
* La DSI de l'UBS sur eduroam |
|||
* Orange sur les livebox |
|||
* Lumen sur du transatlantique |
|||
* Autre transitaire fournissant le service au serveur visé |
|||
* Attaquant sur le réseau local (attention aux LP Cyber qui jouent par là...) |
|||
* ... |
|||
* L'objectif de la crypto : communiquer de manière *sûre* sur un medium *non sûr* |
|||
|
|||
|
|||
Communiquer de manière sûre ? |
|||
============================= |
|||
|
|||
1. Confidentialité : chiffrement |
|||
2. Intégrité : signature/scellement |
|||
3. Authentification : preuve de possession de matériel crypto |
|||
4. Non-répudiation : signature |
|||
|
|||
|
|||
La cryptographie moderne |
|||
======================== |
|||
|
|||
La cryptographie asymétrique : |
|||
* Chaque acteur a une paire de clés publique/privée reliées mathématiquement |
|||
* Chiffrer = utiliser la clé publique de l'interlocuteur, déchiffrer = utiliser sa propre clé privée (tout le monde peut nous parler, nous seuls pouvons comprendre) |
|||
* Signer = utiliser sa propre clé privée, vérifier = utiliser la clé publique de l'interlocuteur (nous seuls pouvons signer, tout le monde peut vérifier) |
|||
* Exemples : RSA, ECDSA |
|||
|
|||
La cryptographie symétrique : |
|||
* Chaque paire d'acteurs a une clé secrète |
|||
* Cette clé secrète est utiliser pour chiffrer/déchiffrer et sceller/vérifier |
|||
* Exemple : AES, HMAC |
|||
|
|||
Le hachage : |
|||
* Empreinte de taille fixe à sens unique (non inversible) |
|||
* Hachage crypto doit être robuste aux attaques (collision, pré-images) |
|||
* Exemples SHA-256, SHA3-512 |
|||
|
|||
Quelle taille de clé ? [KeyLength](https://www.keylength.com/) |
|||
|
|||
|
|||
La mise en œuvre |
|||
================ |
|||
|
|||
L'obtention des clés : les PKI - Public Key Infrastructure |
|||
---------------------------------------------------------- |
|||
|
|||
* La difficulté majeure côté usage : obtenir la bonne clé. Comment l'obtenir de manière sûre quand le medium est non sûr ? |
|||
* Le risque : parler chiffré mais pas avec le bon interlocuteur (ie, avec Ernest) |
|||
* Les PKI sont des moyens d'associer des clés publiques (donc pour crypto asymétrique) à des identifiants (nom de personne, nom DNS, ...) |
|||
* Quelques modèles : |
|||
* Centralisé CA (autorités de certification) / PKIX |
|||
* Distribué PGP |
|||
* DANE/TLSA dans DNSSEC |
|||
* Diffus style keybase.io |
|||
* L'échange direct / uniquement en out-of-band (donc pas vraiment de PKI) |
|||
* La mise en contact |
|||
|
|||
|
|||
La négociation : les protocoles cryptographiques |
|||
------------------------------------------------ |
|||
|
|||
* Pour communiquer, il faut un standard : un protocole |
|||
* Quelques protocoles cryptographiques : TLS, SSH, S/MIME, PGP, ... |
|||
* Généralement pour la mise en place d'une communication en crypto hybride : |
|||
* Échange de clés symétriques en crypto asymétrique |
|||
* Puis communication *payload* en crypto symétrique |
|||
* Exemple des suites cryptographiques TLS ("ECDHE-RSA-AES128-GCM-SHA256") |
|||
|
|||
|
|||
Exemple : le modèle HTTPS |
|||
------------------------- |
|||
|
|||
* Objectif : un tunnel chiffré entre le client (navigateur) et le serveur |
|||
* Pour cela il nous faut : |
|||
* Un protocole : TLS |
|||
* La (bonne) clé publique du serveur : Certificat |
|||
* Un certificat = (clé publique, nom) signé par un tiers. Ici : |
|||
* clé publique = celle du serveur, il a la clé privée qui va avec |
|||
* nom = nom d'hôte DNS (par exemple www.univ-ubs.fr) |
|||
* tiers = une autorité de certification (par exemple Let's Encrypt) |
|||
* => On a bien une association entre un nom et une clé, ici certifiée par un tiers |
|||
* Le client doit valider la signature de la CA : |
|||
* Il lui faut donc vérifier avec la clé publique de la CA |
|||
* Les clés publiques des CA reconnues par les clients sont pré-installées dans les navigateurs, pas de magie, il faut une *ancre de confiance* dans le logiciel |
|||
|
|||
|
|||
Ce qu'on va faire en TD |
|||
======================= |
|||
|
|||
* TD2.1 : Crypto asymétrique |
|||
* TD3.2 : CA |
@ -0,0 +1,113 @@ |
|||
TD2.1 : Usage de la cryptographie asymétrique |
|||
============================================= |
|||
|
|||
|
|||
Ce TD présente et applique les notions de cryptographie asymétrique : |
|||
|
|||
* Génération de clés RSA |
|||
* Distribution de clés |
|||
* Signature et chiffrement RSA |
|||
|
|||
Le cryptosystème que nous allons utiliser ici est basé sur la fonction RSA. Le cryptosystème proposé est simple et présente donc certaines vulnérabilités mais illustre le fonctionnement. |
|||
|
|||
|
|||
Génération de clés RSA |
|||
====================== |
|||
|
|||
Nous allons commencer par générer une paire de clés RSA pour chacun. Voici l'algorithme simplifié de génération de clés RSA (en réalité, d'autres tests doivent être réalisés) : |
|||
|
|||
* Choisir deux nombres premiers _p_ et _q_ ([exemples de premiers](https://fr.wikipedia.org/wiki/Liste_de_nombres_premiers)) |
|||
* Calculer _n = p * q_ (__Attention, pour que la suite du TD fonctionne, n doit être supérieur à 1000 !__) |
|||
* Calculer _φ(n) = (p-1)(q-1)_ |
|||
* Choisir _e_ tel que : |
|||
* _1 < e < φ(n)_ |
|||
* _pgcd(e, φ(n)) = 1_ |
|||
* Par exemple, un premier qui ne divise pas φ(n) |
|||
* Déterminer l'inverse modulaire _d ≡ e<sup>-1</sup> mod φ(n)_. Vous pouvez utiliser [DCODE](https://www.dcode.fr/inverse-modulaire) pour cela (attention, pas le `pow` Python pour ça, sauf si vous êtes *certain* d'avoir python 3.8 !) <!-- Vous pouvez utiliser [Wolfram Alpha](http://www.wolframalpha.com), avec une requête de la forme `7 ^ -1 mod 1147` (attention, pas le `pow` Python pour ça !) --> |
|||
* La clé publique est _(e,n)_ et la clé privée est _(d,n)_ |
|||
|
|||
Gardez votre clé privée secrète et transmettez votre clé publique à l'enseignant via un _message privé_ dans BBB. Elle sera inscrite dans le registre tenu par l'enseignant et affiché par BBB (la "PKI"). |
|||
|
|||
Les exemples dans la suite du sujet sont réalisés avec p=31, q=37, n=1147, φ(n)=1080, e=7, d=463. La clé publique est _(e,n)_, ici _(7,1147)_, et la clé privée est _(d,n)_, ici _(463,1147)_. |
|||
|
|||
<!-- Code Python pour calculer _a<sup>-1</sup> mod b_ : `modinv(a,b)` disponible [ici](modinv.py) --> |
|||
|
|||
Rappel : la propriété utilisée est que pour tout message _m, m<sup>de</sup>[n] = m_. |
|||
|
|||
Chiffrement et déchiffrement |
|||
============================ |
|||
|
|||
Description |
|||
----------- |
|||
|
|||
Nous allons chiffrer des chaînes de caractères. Pour cela, chaque lettre est remplacée par son rang dans l'alphabet, sur 2 chiffres : |
|||
|
|||
|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|_| |
|||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:| |
|||
|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27| |
|||
|
|||
Par exemple, "crypto" devient `03 18 25 16 20 15` |
|||
|
|||
Ensuite, afin de ne pas retomber dans un chiffrement par substitution simple, les chiffres sont assemblés par blocs de 3 (complété éventuellement de 0 à la fin), ainsi `03 18 25 16 20 15` devient `031 825 162 015`. |
|||
|
|||
Enfin, chaque bloc clair de 3 chiffres est chiffré indépendamment par la fonction RSA : bloc<sub>chiffré</sub> = bloc<sub>clair</sub><sup>e</sup>[n]. Attention, _(e,n)_ représente une clé publique, mais celle de qui ? L'utilisation de la clé _(7,1147)_ donne le chiffré `1116 751 245 1108`. |
|||
|
|||
> Pour calculer les exponentiations modulaires, vous pouvez utiliser python (dans l'interpréteur, tapez `pow(a,b,c)` pour obtenir a<sup>b</sup>[c]) ou [DCODE](https://www.dcode.fr/exponentiation-modulaire)<!--[Wolfram Alpha](http://www.wolframalpha.com)-->. Attention, lors des calculs, n'écrivez pas de '0' en début d'entier. Par exemple, pour le bloc clair `031`, tapez `pow(31,7,1147)`. Commencer un entier par '0' le fait interpréter comme un nombre encodé en _octal_ (même principe qu'un nombre commençant par '0x' qui est interprété comme un hexadécimal). |
|||
|
|||
|
|||
Le déchiffrement est opéré de manière analogue, en utilisant la clé privée au lieu de la clé publique. Chaque bloc clair est réobtenu à partir du bloc chiffré par le calcul : bloc<sub>clair</sub> = bloc<sub>chiffré</sub><sup>d</sup>[n] |
|||
|
|||
Mise en pratique |
|||
---------------- |
|||
|
|||
Vous allez maintenant transmettre un message chiffré à un autre étudiant. Pour cette partie, contrairement aux explications en début de sujet, vous pouvez déposer ce message chiffré sur le chat du général et non en message privé : le chiffrement assure la _confidentialité_ du message transmis. |
|||
|
|||
1. **Chiffrement de votre message** : Chiffrez un message de votre choix avec le cryptosystème proposé. |
|||
2. **Envoi de votre message** : Écrivez le message chiffré dans le chat du BBB général. |
|||
3. **Réception d'un message** : À la réception d'un message, appliquez l'algorithme de déchiffrement. Quelqu'un d'autre pouvait-il obtenir le clair de ce message ? |
|||
|
|||
|
|||
Signature et vérification |
|||
========================= |
|||
|
|||
Description |
|||
----------- |
|||
|
|||
Nous allons signer des chaînes de caractères. Pour cela, chaque lettre est remplacée par son rang dans l'alphabet. Pour un message _m = (m<sub>0</sub>, ..., m<sub>i</sub>)_ avec _(m<sub>0</sub>, ..., m<sub>i</sub>)_ les rangs de chaque lettre (attention, on ne fait plus des blocs de 3 chiffres ici), le haché _h(m)_ est calculé par l'algorithme suivant : |
|||
|
|||
h = 2; |
|||
for (j=0; j<i; j++) { |
|||
h = h * 2; |
|||
h = h + m[j]; |
|||
} |
|||
return h%1000; |
|||
|
|||
La valeur de la signature vaut alors _h(m)<sup>d</sup>[n]_. Attention, _(d,n)_ représente une clé privée, mais celle de qui ? Le haché de "crypto" vaut par exemple 831 et la signature par _(463,1147)_ est 335. |
|||
|
|||
Le message est alors envoyé accompagné de sa signature. La vérification d'un message reçu _m_ signé avec _sig_ est opérée de la manière suivante : |
|||
|
|||
* Calculer _h(m)_ par rapport au _m_ reçu |
|||
* Calculer _sig<sup>e</sup>[n]_ |
|||
* Vérifier que _h(m) == sig<sup>e</sup>[n]_ sur le message reçu |
|||
|
|||
|
|||
Mise en pratique |
|||
---------------- |
|||
|
|||
Vous allez maintenant transmettre un message clair (non chiffré) signé à un autre étudiant, par message privé. La signature permet de vérifier l'_intégrité_ du message transmis. |
|||
|
|||
1. **Signature de votre message** : Signez un message de votre choix avec le cryptosystème proposé. |
|||
1. **Envoi de votre message** : Écrivez le message par message privé (attention, il faut bien envoyer le message en clair + la signature !) |
|||
3. **Réception d'un message** : À la réception d'un message, appliquez l'algorithme de vérification de la signature. Le message reçu est-il intègre ? Si non, quelle attaque avez-vous détectée ? |
|||
|
|||
|
|||
Attaques sur le cryptosystème proposé |
|||
===================================== |
|||
|
|||
Étudiez et testez quelques attaques sur le système mis en place : |
|||
|
|||
* Modification de message en conservant la validité de la signature |
|||
* Attaque de la clé privée (par factorisation de _n_ par exemple) |
|||
|
|||
|
|||
Toutes ces attaques sont possibles ici. Réfléchissez à leur cause et aux protections mises en place dans les cryptosystèmes réels. Implémentez une (ou plusieurs) attaque dans le langage de votre choix, proposez une contre-mesure et évaluez la complexité rajoutée par votre contre-mesure. |
Loading…
Reference in new issue