Browse Source

cm2 et td2.1

master
Francois Lesueur 3 years ago
parent
commit
77371417a2
  1. 6
      README.md
  2. 106
      cm2-crypto.md
  3. 113
      td2.1-crypto.md

6
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
<!-- * [TD1.2](td1.2-shell.md) Wargame shell -->
* 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/))

106
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

113
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 _&phi;(n) = (p-1)(q-1)_
* Choisir _e_ tel que :
* _1 < e < &phi;(n)_
* _pgcd(e, &phi;(n)) = 1_
* Par exemple, un premier qui ne divise pas &phi;(n)
* Déterminer l'inverse modulaire _d &equiv; e<sup>-1</sup> mod &phi;(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, &phi;(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…
Cancel
Save