diff --git a/README.md b/README.md index b7ec767..8449277 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Cette page recense les séances du module M3102 "Services réseaux". L'objectif Ce module se situe entre M2102 (Couches OSI, de la modulation à IP, avec un peu de routage/adressage IP) et M4101C. Il dure 6 semaines, avec chaque semaine 1 séance de cours (1h30) et 2 séances de TD (2*1h30) (attention, pour des raisons d'edt, la séance de cours a en fait lieu à la fin de la semaine précédent les TD). Le contenu sera détaillé au fur et à mesure de la période. -Une large part des séances pratiques sera réalisée sur la plateforme MI-LXC (https://github.com/flesueur/mi-lxc), pour laquelle il faudra télécharger une VM Virtualbox **avant** le TD1.2 "Découverte de MI-LXC" : [.ova à télécharger ici](https://filesender.renater.fr/?s=download&token=2ca6036b-49b8-4b4c-93bb-95c5de051400). Il faudra arriver en séance avec Virtualbox installé et le .ova de MI-LXC déjà téléchargé, l'installation et la découverte de la VM seront ensuite le programme de la séance TD1.2. +Une large part des séances pratiques sera réalisée sur la plateforme MI-LXC (https://github.com/flesueur/mi-lxc), pour laquelle il faudra télécharger une VM Virtualbox **avant** le TD1.1 "Découverte de MI-LXC" : [.ova à télécharger ici](https://filesender.renater.fr/?s=download&token=2ca6036b-49b8-4b4c-93bb-95c5de051400). Il faudra arriver en séance avec Virtualbox installé et le .ova de MI-LXC déjà téléchargé, l'installation et la découverte de la VM seront ensuite le programme de la séance TD1.2. ## Programme @@ -16,8 +16,8 @@ Une large part des séances pratiques sera réalisée sur la plateforme MI-LXC ( * [TD1.1](td1.1-milxc.md) Découverte MI-LXC * S2 : - * CM2 Cryptographie et sécurité des communications (complément en ligne : [Section "Bases de la crypto"](https://github.com/flesueur/csc/blob/master/cours.md#bases-de-la-crypto)) - * TD2.1 Cryptogaphie JdR + * [CM2](cm2-crypto.md) Cryptographie et sécurité des communications (complément en ligne : [Section "Bases de la crypto"](https://github.com/flesueur/csc/blob/master/cours.md#bases-de-la-crypto)) + * [TD2.1](td2.1-crypto.md) Cryptographie JdR * TD2.2 Apache/CMS * S3 : * CM3 DNS (complément en ligne : [S. Bortzmeyer](https://www.iletaitunefoisinternet.fr/post/1-dns-bortzmeyer/)) diff --git a/cm2-crypto.md b/cm2-crypto.md new file mode 100644 index 0000000..8bf91af --- /dev/null +++ b/cm2-crypto.md @@ -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 diff --git a/td2.1-crypto.md b/td2.1-crypto.md new file mode 100644 index 0000000..1b4ae8d --- /dev/null +++ b/td2.1-crypto.md @@ -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-1 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 !) +* 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)_. + + + +Rappel : la propriété utilisée est que pour tout message _m, mde[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 : blocchiffré = blocclaire[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 ab[c]) ou [DCODE](https://www.dcode.fr/exponentiation-modulaire). 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 : blocclair = blocchiffréd[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 = (m0, ..., mi)_ avec _(m0, ..., mi)_ 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; jd[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 _sige[n]_ +* Vérifier que _h(m) == sige[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.