Du bloc au message

Chiffrement par blocs et bourrage (padding)

Un chiffrement par blocs comme l'AES ne sait faire qu'une seule chose : transformer un bloc de taille fixe en un autre bloc de même taille, sous le contrôle d'une clé. Pour l'AES, ce bloc fait 128 bits, soit 16 octets. Ni plus, ni moins.

Le problème des messages réels

Un message réel — un courriel, un fichier, une requête HTTPS — fait rarement pile 16 octets. Il faut donc le découper en une suite de blocs de 16 octets, puis chiffrer chaque bloc.

Message clair (37 octets)
+----------------+----------------+-----+
| bloc 1 (16 o.) | bloc 2 (16 o.) | ... |
+----------------+----------------+-----+
                                     ^
                          5 octets seulement : trop court !

Presque toujours, la taille du message n'est pas un multiple de 16. Le dernier bloc est incomplet. Que faire de ces octets manquants ?

Le bourrage (padding)

On complète le dernier bloc avec des octets supplémentaires : c'est le bourrage, ou padding. Mais on ne peut pas mettre n'importe quoi : au déchiffrement, il faut savoir exactement combien d'octets retirer, sinon le message est corrompu.

La méthode standard est PKCS#7. Sa règle est élégante : si k octets manquent, on ajoute k octets valant chacun k.

Il manque 3 octets -> on ajoute : 03 03 03
Il manque 1 octet  -> on ajoute : 01
Il manque 6 octets -> on ajoute : 06 06 06 06 06 06

Au déchiffrement, on lit le dernier octet : il donne le nombre d'octets de bourrage à retirer.

Le cas piège : le message déjà aligné

Que se passe-t-il si le message fait déjà un multiple de 16 octets ? Si l'on n'ajoutait rien, le déchiffreur lirait le dernier octet des vraies données et croirait à tort que c'est du bourrage.

La solution de PKCS#7 : on ajoute toujours du bourrage, même dans ce cas. Un message aligné reçoit alors un bloc entier de bourrage :

16 octets de padding = 10 10 10 ... 10  (16 fois la valeur 16, en hexadécimal)

Il y a donc toujours entre 1 et 16 octets de bourrage. Le déchiffrement n'est jamais ambigu.

Compter les blocs

Pour un message de L octets avec une taille de bloc B, le nombre de blocs après bourrage est :

nombre_de_blocs = plancher(L / B) + 1

Le + 1 traduit le fait qu'il y a toujours au moins un octet de bourrage : même un message aligné gagne un bloc.

En résumé

  • L'AES chiffre des blocs de taille fixe : 16 octets (128 bits).
  • Un message est découpé en blocs ; le dernier est complété par un bourrage.
  • PKCS#7 ajoute k octets valant k, et ajoute toujours du bourrage — même un bloc entier si le message est déjà aligné.
  • Le déchiffrement lit le dernier octet pour savoir combien d'octets retirer, sans ambiguïté.