Aller au contenu

TD2 — Chiffrement symetrique : AES et modes d'operation

Duree : 2h | Par groupe

Prerequis : CM2 — Cryptographie symetrique Rendu : depot Forgejo Dependance : pip install cryptography

Objectifs

  • Manipuler les representations decimal / hexadecimal / ASCII utilisees par AES
  • Sentir le fonctionnement interne d'un round AES (sans entrer dans la theorie des corps de Galois)
  • Maitriser le padding PKCS7
  • Comprendre pourquoi ECB est dangereux et comment CBC corrige le probleme
  • Implementer AES-ECB et AES-CBC en Python

Plan

  1. Exercices sur papier (1h) — six exercices pour batir l'intuition
  2. Exercices de programmation (1h) — implementation et effet pingouin

Exercices sur papier

A la main

Ces exercices se font sans ordinateur. Utiliser la table ASCII en annexe.

Exercice 1 — Conversions decimal / hexadecimal

L'AES manipule des octets. Chaque octet (8 bits) s'ecrit avec 2 chiffres hexadecimaux (de 00 a FF).

Sous-partie A — Conversions

Convertir en hexadecimal :

Decimal Hex
65 ?
200 ?
255 ?
16 ?

Convertir en decimal :

Hex Decimal
4A ?
FF ?
1F ?
B0 ?

Sous-partie B — Encodage ASCII

A l'aide de la table ASCII (annexe), encoder en hexadecimal les mots suivants (un octet par caractere) :

  • AES
  • Crypto
  • Hello!

Sous-partie C — XOR sur octets

Le XOR () est l'operation fondamentale d'AES. Sur deux bits : 0⊕0 = 0, 0⊕1 = 1, 1⊕0 = 1, 1⊕1 = 0.

Sur deux octets, on XOR bit a bit. Exemple : 4A ⊕ 35 :

4A  =  0100 1010
35  =  0011 0101
---------------
       0111 1111  =  7F

Calculer :

  • FF ⊕ 0F = ?
  • A5 ⊕ A5 = ?
  • 41 ⊕ 20 = ? (que vaut 'A' XOR espace en ASCII ? Que represente le resultat ?)
  • 42 ⊕ 0F = ?

Exercice 2 — Sentir AES : un round complet a la main

AES traite des blocs de 16 octets organises en une matrice 4x4 (column-major). Un round applique 4 operations dans l'ordre :

AddRoundKey → SubBytes → ShiftRows → MixColumns

(Le tout premier round commence par AddRoundKey ; le dernier round saute MixColumns.)

On va executer un round sur le texte BONJOUR LES AMIS (16 caracteres) avec une sous-cle simple.

Question 1 — Construire la matrice d'etat

Encoder les 16 caracteres en hexadecimal (table ASCII), puis remplir la matrice 4x4 colonne par colonne :

col 0 col 1 col 2 col 3
? ? ? ?
? ? ? ?
? ? ? ?
? ? ? ?

Question 2 — AddRoundKey

Sous-cle (matrice 4x4 de 0F partout) :

0F 0F 0F 0F
0F 0F 0F 0F
0F 0F 0F 0F
0F 0F 0F 0F

XOR position par position avec la matrice d'etat. Ecrire la matrice resultante.

Question 3 — SubBytes

On remplace chaque octet par sa valeur dans la S-Box d'AES (table de substitution non-lineaire fixe). Pour un octet XY (en hex), la valeur de remplacement se trouve a la ligne X, colonne Y de la S-Box.

Extrait de la S-Box AES (lignes 2, 4, 5 — suffisantes pour cet exercice) :

0 1 2 3 4 5 6 7 8 9 A B C D E F
2 B7 FD 93 26 36 3F F7 CC 34 A5 E5 F1 71 D8 31 15
4 09 83 2C 1A 1B 6E 5A A0 52 3B D6 B3 29 E3 2F 84
5 53 D1 00 ED 20 FC B1 5B 6A CB BE 39 4A 4C 58 CF

Exemple : 4D → ligne 4, colonne DE3.

Appliquer SubBytes a chaque octet de la matrice obtenue en Q2.

Question 4 — ShiftRows

Decaler chaque ligne vers la gauche (rotation circulaire) :

  • Ligne 0 : pas de decalage
  • Ligne 1 : decalage de 1
  • Ligne 2 : decalage de 2
  • Ligne 3 : decalage de 3

Ecrire la matrice resultante.

Question 5 — MixColumns (a comprendre, pas a calculer)

MixColumns multiplie chaque colonne par une matrice fixe dans le corps de Galois GF(2^8). Ce calcul depasse le cadre du TD : on en garde l'intuition et le role.

Role : MixColumns diffuse chaque octet sur toute la colonne. Apres MixColumns, chaque octet de sortie depend des 4 octets de la colonne d'entree.

Question 6 — Reflexion : pourquoi 10 rounds ?

Apres un seul round, si on change un bit du message d'entree, combien d'octets de la sortie sont affectes ? Apres 2 rounds ? Apres 10 rounds ?


Exercice 3 — Padding PKCS7

AES chiffre par blocs de 16 octets. Si le message n'est pas un multiple de 16, on complete avec PKCS7 : on ajoute n octets, chacun de valeur n.

Si le message fait deja un multiple de 16, on ajoute un bloc complet de 16 octets de valeur 0x10 (= 16).

Question 1 — Calculer le padding

Pour chaque taille de message, indiquer la valeur des octets de padding et le nombre d'octets ajoutes :

Taille message (octets) Octets ajoutes Valeur des octets
13 ? ?
5 ? ?
1 ? ?
16 ? ?
31 ? ?

Question 2 — Retirer le padding

Apres dechiffrement, on obtient les octets suivants (en hex). Donner le message original (sans padding) :

a) 48 65 6C 6C 6F 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B b) 54 65 73 74 21 21 21 21 21 21 21 21 04 04 04 04

Question 3 — Pourquoi toujours padder, meme un message multiple de 16 ?


Exercice 4 — Le mode ECB est dangereux

Le mode ECB (Electronic Code Book) chiffre chaque bloc independamment avec la meme cle.

Bloc 1 ──[AES_K]──> Bloc chiffre 1
Bloc 2 ──[AES_K]──> Bloc chiffre 2
Bloc 3 ──[AES_K]──> Bloc chiffre 3

Question 1 — Si deux blocs du message clair sont identiques, que peut-on dire des blocs chiffres correspondants ?

Question 2 — Le salaire de Jane

Dans une entreprise, les salaires sont stockes dans une base de donnees, chiffres avec AES en mode ECB. Pour la demonstration, la fonction de chiffrement utilise des blocs de 2 caracteres (au lieu de 16).

Vous savez que Jack gagne 105 000 EUR/an. Son entree chiffree dans la base est :

Q9 2D FP VX C9 IO

Vous trouvez l'entree chiffree de Jane, la patronne de Jack. Elle figure parmi les 5 candidats suivants :

Candidat Cipher
1 TO AV 6R FP Y5 VX C9
2 YP FG FP DF DF IO
3 Q9 AX FP C9 IO IO
4 AC ED 4T FP VX IO IO
5 UT JS DG FP RT AV IO

Sachant que Jane est la patronne (donc gagne plus que Jack) et que la structure du salaire suit le meme format pour tous les employes, lequel de ces candidats est le salaire de Jane ? Justifier en utilisant la propriete d'ECB.

Question 3 — Pourquoi ECB est-il deplorable pour les images ?

Imaginez une photo encodee en pixels : de nombreuses zones de couleur uniforme (ciel bleu, mur blanc, peau...) produisent des blocs de pixels identiques. Que va-t-il rester visible sur l'image chiffree en ECB ?


Exercice 5 — Le mode CBC corrige ECB

Le mode CBC (Cipher Block Chaining) XOR chaque bloc clair avec le bloc chiffre precedent avant de chiffrer. Le premier bloc utilise un vecteur d'initialisation (IV) aleatoire.

Bloc 1 ⊕ IV  ──[AES_K]──> Bloc chiffre 1
Bloc 2 ⊕ C1  ──[AES_K]──> Bloc chiffre 2
Bloc 3 ⊕ C2  ──[AES_K]──> Bloc chiffre 3

Question 1 — Schema

Dessiner le schema de chiffrement CBC pour 3 blocs (sur papier ou tableau).

Question 2 — Chiffrement CBC a la main

Pour rendre l'exercice tractable, on remplace AES par un chiffrement simplifie :

\[E_K(\text{bloc}) = \text{bloc} \oplus K\]

avec des blocs de 8 bits (1 octet).

Donnees :

  • Cle : $K = $ 5A
  • IV : 3C
  • Message clair : 4 blocs = A1 B2 C3 D4

Calculer les 4 blocs chiffres \(C_1, C_2, C_3, C_4\). Detailler chaque etape XOR.

Question 3 — Dechiffrement CBC

Avec la meme cle $K = $ 5A et le meme IV = 3C, dechiffrer le message :

C7 2F B6 38

(Indication : la fonction de dechiffrement est \(D_K(C) = C \oplus K\) ; puis appliquer l'inverse de CBC.)

Question 4 — Reflexion

a) Si on chiffre deux fois le meme message avec la meme cle mais des IV differents, les chiffres sont-ils identiques ? b) Que se passe-t-il si on reutilise le meme IV avec la meme cle pour deux messages differents qui partagent le meme premier bloc ? c) Pourquoi CBC corrige-t-il le probleme d'ECB observe a l'exercice 4 ?


Exercice 6 — Attaque par clair connu sur XOR

Un systeme naif chiffre les messages par simple XOR avec une cle repetee : $\(C_i = M_i \oplus K_{i \bmod |K|}\)$

Question 1 — Retrouver la cle a partir d'un clair connu

On vous donne un message clair \(M\) et son chiffre \(C\) :

  • \(M\) = HELLO → en hex : 48 45 4C 4C 4F
  • \(C\) = 68 65 6C 6C 6F

Trouver la cle \(K\) (1 octet).

Question 2 — Dechiffrer un nouveau message

Avec la meme cle $K = $ 20, dechiffrer le message intercepte $C' = $ world (en hex : 77 6F 72 6C 64).

Question 3 — Attaque a clair partiellement connu

On intercepte le message chiffre suivant (en hex), produit avec une cle multi-octets repetee :

03 2D 2D 2B 2D 36 33 62 02 2D 2B 20 24

Vous savez que le message clair commence par Bonjour (7 caracteres).

a) Calculer les 7 premiers octets de la cle. b) Quelle est la longueur probable de la cle ? (Indice : observer la periodicite dans les octets retrouves.) c) Dechiffrer le message complet.

Question 4 — Discussion

a) Pourquoi le chiffrement XOR avec cle courte est-il vulnerable ? b) Et si la cle est aussi longue que le message et utilisee une seule fois ? (= One-Time Pad, OTP). Quel(s) probleme(s) cela pose-t-il en pratique ?


Exercices de programmation (Python)

Programmation

Les exercices suivants se font en Python avec la bibliotheque cryptography (pip install cryptography).

Structure du projet

Telecharger le scaffolding (td2-template.zip)

td2/
├── README.md
├── aes_ecb.py        # chiffrer_ecb / dechiffrer_ecb
├── aes_cbc.py        # chiffrer_cbc / dechiffrer_cbc
├── pinguin.py        # chiffrer_image_ecb / chiffrer_image_cbc
└── images/
    └── tux.bmp       # fourni

Partie 7 — AES-ECB : chiffrement texte

Fichier : aes_ecb.py

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import padding
import os

def chiffrer_ecb(message: bytes, cle: bytes) -> bytes:
    """
    Chiffre un message en AES-ECB.
    - Applique le padding PKCS7 avant de chiffrer.
    - cle doit faire 16, 24 ou 32 bytes (128, 192 ou 256 bits).
    """
    pass

def dechiffrer_ecb(chiffre: bytes, cle: bytes) -> bytes:
    """
    Dechiffre un message chiffre en AES-ECB.
    - Retire le padding PKCS7 apres dechiffrement.
    """
    pass

Test revelateur :

cle = os.urandom(32)
# Deux blocs identiques dans le message
message = b"AAAAAAAAAAAAAAAA" + b"AAAAAAAAAAAAAAAA"
chiffre = chiffrer_ecb(message, cle)
print(f"Bloc 1 : {chiffre[:16].hex()}")
print(f"Bloc 2 : {chiffre[16:32].hex()}")
print(f"Identiques ? {chiffre[:16] == chiffre[16:32]}")

README

Les deux blocs chiffres sont-ils identiques ? Qu'est-ce que cela implique pour la securite ?


Partie 8 — L'effet pingouin

Fichier : pinguin.py

def chiffrer_image_ecb(chemin_entree: str, chemin_sortie: str, cle: bytes) -> None:
    """
    Chiffre les pixels d'une image BMP en AES-ECB.
    - Conserver le header BMP (54 premiers bytes) tel quel.
    - Chiffrer uniquement les donnees pixel (apres le header).
    - Appliquer un padding si necessaire.
    - Ecrire header original + pixels chiffres dans chemin_sortie.
    """
    pass

def chiffrer_image_cbc(chemin_entree: str, chemin_sortie: str, cle: bytes, iv: bytes) -> None:
    """
    Chiffre les pixels d'une image BMP en AES-CBC.
    Meme principe que ECB, mais avec CBC.
    """
    pass

Instructions :

  1. Generer une cle aleatoire : cle = os.urandom(32)
  2. Generer un IV aleatoire : iv = os.urandom(16)
  3. Chiffrer tux.bmp en ECB → tux_ecb.bmp
  4. Chiffrer tux.bmp en CBC → tux_cbc.bmp
  5. Ouvrir les trois images cote a cote et comparer

README

Decrire ce qu'on voit sur chaque image. Expliquer pourquoi ECB revele des informations et pourquoi CBC ne le fait pas.


Partie 9 — AES-CBC : chiffrement texte

Fichier : aes_cbc.py

def chiffrer_cbc(message: bytes, cle: bytes, iv: bytes) -> bytes:
    """
    Chiffre un message en AES-CBC.
    - Applique le padding PKCS7.
    - iv doit faire 16 bytes.
    """
    pass

def dechiffrer_cbc(chiffre: bytes, cle: bytes, iv: bytes) -> bytes:
    """
    Dechiffre un message chiffre en AES-CBC.
    - Retire le padding PKCS7.
    """
    pass

Test :

cle = os.urandom(32)
iv = os.urandom(16)
message = b"AAAAAAAAAAAAAAAA" + b"AAAAAAAAAAAAAAAA"
chiffre = chiffrer_cbc(message, cle, iv)
print(f"Bloc 1 : {chiffre[:16].hex()}")
print(f"Bloc 2 : {chiffre[16:32].hex()}")
print(f"Identiques ? {chiffre[:16] == chiffre[16:32]}")

README

Comparer avec le resultat ECB. Pourquoi CBC est-il plus sur pour ce cas ?


Annexe — Table ASCII (caracteres imprimables)

Symboles et chiffres

Char Dec Hex Char Dec Hex Char Dec Hex
(espace) 32 20 0 48 30 @ 64 40
! 33 21 1 49 31 [ 91 5B
" 34 22 2 50 32 \ 92 5C
# 35 23 3 51 33 ] 93 5D
$ 36 24 4 52 34 ^ 94 5E
% 37 25 5 53 35 _ 95 5F
& 38 26 6 54 36 ` 96 60
' 39 27 7 55 37 { 123 7B
( 40 28 8 56 38 \| 124 7C
) 41 29 9 57 39 } 125 7D
* 42 2A : 58 3A ~ 126 7E
+ 43 2B ; 59 3B
, 44 2C < 60 3C
- 45 2D = 61 3D
. 46 2E > 62 3E
/ 47 2F ? 63 3F

Lettres majuscules

Char Dec Hex Char Dec Hex Char Dec Hex Char Dec Hex
A 65 41 H 72 48 O 79 4F V 86 56
B 66 42 I 73 49 P 80 50 W 87 57
C 67 43 J 74 4A Q 81 51 X 88 58
D 68 44 K 75 4B R 82 52 Y 89 59
E 69 45 L 76 4C S 83 53 Z 90 5A
F 70 46 M 77 4D T 84 54
G 71 47 N 78 4E U 85 55

Lettres minuscules

Char Dec Hex Char Dec Hex Char Dec Hex Char Dec Hex
a 97 61 h 104 68 o 111 6F v 118 76
b 98 62 i 105 69 p 112 70 w 119 77
c 99 63 j 106 6A q 113 71 x 120 78
d 100 64 k 107 6B r 114 72 y 121 79
e 101 65 l 108 6C s 115 73 z 122 7A
f 102 66 m 109 6D t 116 74
g 103 67 n 110 6E u 117 75

README a rendre

# TD2 — AES en pratique

## Exercices sur papier

### Exercice 1 — Conversions

- Reponses sous-partie A (decimal → hex et hex → decimal) : \_\_\_
- Reponses sous-partie B (encodage ASCII de AES, Crypto, Hello!) : \_\_\_
- Reponses sous-partie C (XOR octets) : \_\_\_

### Exercice 2 — Round AES

- Matrice d'etat initiale : \_\_\_
- Apres AddRoundKey : \_\_\_
- Apres SubBytes : \_\_\_
- Apres ShiftRows : \_\_\_
- Reflexion sur les 10 rounds : \_\_\_

### Exercice 3 — Padding PKCS7

- Tableau des paddings : \_\_\_
- Messages originaux Q2 a) et b) : \_\_\_
- Pourquoi padder un message multiple de 16 ? : \_\_\_

### Exercice 4 — ECB et salaire de Jane

- Salaire de Jane = candidat n°\_\_\_
- Justification (proprietes ECB) : \_\_\_
- Pourquoi ECB est deplorable pour les images : \_\_\_

### Exercice 5 — CBC a la main

- Chiffrement (C1 C2 C3 C4) : \_\_\_
- Dechiffrement : \_\_\_
- Reflexion IV : \_\_\_

### Exercice 6 — Attaque XOR

- Cle Q1 : \_\_\_
- Dechiffrement Q2 : \_\_\_
- Cle Q3 et message dechiffre : \_\_\_
- Discussion XOR vs OTP : \_\_\_

## Exercices Python

### Partie 7 — ECB et blocs identiques

- Les deux blocs chiffres sont-ils identiques ? \_\_\_
- Qu'est-ce que cela implique pour la securite ? (2-3 phrases)

### Partie 8 — Effet pingouin

- Decrire ce qu'on voit sur tux_ecb.bmp :
- Decrire ce qu'on voit sur tux_cbc.bmp :
- Expliquer pourquoi ECB revele des informations :
- Expliquer pourquoi CBC ne le fait pas :

### Partie 9 — CBC et blocs identiques

- Les deux blocs chiffres sont-ils identiques en CBC ? \_\_\_
- Comparaison avec ECB :

## Difficultes rencontrees

(libre)