09 May 2014

Implémentation de AES en C/C++

Pour avoir eu un peu du mal à trouver une SPEC d'implémentation claire et concise sur AES quand j'en avais besoin, j'ai donc décidé de partager avec vous quelques petits détails d'implémentation qui pourraient être utiles.

Quelques points à connaître sur AES:

AES (Advenced Encryption System) successeur de DES (Digital Encryption System) est un algorithme de chiffrement symétrique ou à clé secrete par opposition aux algorithmes de chiffrements asymétrique ou à clé publique (ex: RSA, EL Gamal, etc).
AES supporte trois tailles de clés différentes: 128 bits, 192 bits et 256 bits, c'est pourquoi dans la pratique, on parle toujours de AES-128, AES-192 ou AES-256 pour préciser la taille de la clé utilisée.
AES réalise un chiffrement par bloc 128 bits, et comme tout chiffrement par bloc, AES utilise les modes (standards) de chaînage de bloc: ECB (Electronic Code Blook), CBC(Cipher Block Chaining). etc. On parlera donc de AES-128-ECB, AES-256-CBC, ... 
Et puisqu'on ne peut pas être sûr d'avoir que des blocs de 128 bits, on donc besoin de faire du padding: qui consiste à compléter le dernier bloc à 128 bits. Et pour éviter que chacun fasse son padding de son coté, des standards existent justement pour mettre tout le monde d'accord. Car c'est facile de mettre du bruit à la fin pour compléter un bloc à 128 bits, mais de l'autre coté faudrait pouvoir le détecter et l'éliminer lors du déchiffrement, sinon on violerait un des principes fondamentales de la sécurité de l'information qui est: l'intégrité.

Notations: On notera Nk le nombre de mots de 32 bits que contient une clé de chiffrement, ex: Nk = 4 pour une clé de 128 bits.

Nr le nombre de round à effectuer pour une taille de clé donnée, Nr = 10, 12, 14 respectivement pour une clé de 128, 192, 256 bits.
AES opère sur une matrice de 4x4  octets d'élément dans F256, notée state.

Implémentation:

une description de la moulinette de chiffrement AES peut se formaliser de manière suivante (en pseudo code C):

AES_Encrypt(State, K)

{

       KeyExpansion(K, RoundKeys);

       /* Addition initiale */

       AddRoundKey(State, RoundKeys[O]);

       /* Les Nr­1 rondes */

       for (r=1; i<Nr; r++) {

           SubBytes(State);

           ShiftRows(State);

           MixColumns(State);

           AddRoundKey(State, RoundKeys[r]);

       }

       /* FinalRound */

       SubBytes(State);

       ShiftRows(State);

       AddRoundKey(State, RoundKeys[Nr]);

}

En attendant de trouver un peu de temps pour décortiquer dans les détails l'implémentation cet algorithme de chiffrement symétrique qui est actuellement le plus utilisé pour le chiffrement des transactions numériques, je laisse à votre disposition une implémentation au quelle j'ai participé.
L'implémentation en question se retrouve dans le cadre d'un projet qui visait à mettre en place une espèce de calculette cryptographique implémentant plusieurs algorithmes de chiffrement (dont AES) et de hachage. (écrit en C/C++ avec une interface graphique faite avec QT)
lien du repository: https://bitbucket.org/blackhook/cryptocalc/src