Chiffrage aes: algorithme de rijndael

Soyez le premier à donner votre avis sur cette source.

Snippet vu 24 065 fois - Téléchargée 30 fois

Contenu du snippet

Le tout nouveau standard de chiffrage AES 'Advanced Encryption Standard). Plus puissant que tous les chiffrages existant (rsa, des, 3des,etc.).
Un petit bemol: Il est en C et non en C++, mais il est pas mal fait. Et d'ailleurs, le C++ n'est pas plus adapté que le c pour le faire.
Il faut aussi savoir que le chiffrage AES n'est pas encore légalisé en France. Il n'est pas breveté et enfin, il s'appuie sur le magnifique Algorithme de Rijndael.

Ce chiffrage utilise une clé de 128 bits, matérialisés par 16 caractères quelconques.
Vous n'avez qu'à le mettre dans un bon code présentant un menu et vous pourrez l'utiliser.
Pour ceux qui veulent le beurre, l'argent du beurre et quelqu'un pour le leur mettre à la bouche, pas de Pb: Cherchez juste le code chiffreur de fichier que j'ai aussi posté.

Source / Exemple :


unsigned char rcon(int i)

/*
 calcule la constante de round
 en fait, renvoie, pour i valeur d'entree, la valeur 2 ** (i - 1).

  • /
{ int p; unsigned char j=1; for (p = 0; p < i - 1; p++) j = j*2; return j; } unsigned char sub_s_box(unsigned char c, unsigned char cmd) /* effectue le produit matriciel de l'octet c passe en parametre avec la matrice de la s_box: [1 0 0 0 1 1 1 1] [1 1 0 0 0 1 1 1] [1 1 1 0 0 0 1 1] [1 1 1 1 0 0 0 1] [1 1 1 1 1 0 0 0] [0 1 1 1 1 1 0 0] [0 0 1 1 1 1 1 0] [0 0 0 1 1 1 1 1]
  • /
{ int i,nb_1 = 0; unsigned char s_box[8]; unsigned char temp[8]; unsigned char r[8]; if (cmd == 'c') { s_box[0] = 143; //matrice de la s_box (une case du tableau correspond a une ligne de la matrice) s_box[1] = 199; s_box[2] = 227; s_box[3] = 241; s_box[4] = 248; s_box[5] = 124; s_box[6] = 62; s_box[7] = 31; } else { s_box[0] = 37; //matrice inverse de la s_box (decryptage) s_box[1] = 146; s_box[2] = 73; s_box[3] = 164; s_box[4] = 82; s_box[5] = 41; s_box[6] = 148; s_box[7] = 74; } for (i = 0; i < 8; i++) temp[i] = s_box[i] & c; //ET bit a bit for (i = 0; i < 8; i++) { nb_1=0; do { if (temp[i] % 2 != 0) { temp[i] -= 1; nb_1++; //calcul du nombre de '1' dans le code binaire de temp[i] } temp[i] /= 2; } while (temp[i]>0); r[i] = nb_1 % 2; } //generation du résultat de la multiplication matricielle return (r[0]*rcon(8) + r[1]*rcon(7) + r[2]*rcon(6) + r[3]*rcon(5) + r[4]*rcon(4) + r[5]*rcon(3) + r[6]*rcon(2) + r[7]*rcon(1)); } unsigned char multi(char a, char b) /* effectue la multiplication des deux caractères passés en paramètre cette multiplication doit etre bijective
  • /
{ int bb[4] = {0,0,0,0}, p = 0, intemp; unsigned char temp[4]; temp[0] = b; /* ici on récupère les 4 bits de poids faible de b. en fait, l'octet le plus élevé (si on le regarde comme une valeur décimale) que l'on passe dans b est 14 (cf. fonction mix_column) */ do { if (temp[0] % 2 != 0) { temp[0] -= 1; bb[p] = 1; } p++; temp[0] /= 2; } while (temp[0] > 0); temp[0] = a; temp[1] = a; for(p = 1; p < 4; p++) /* on calcule les 4 multiples succéssifs de a */ { intemp = temp[p] * 2; if (intemp > 255) temp[p] = (intemp - 256) ^ 27; else temp[p] = intemp; if (p < 3) temp[p + 1] = temp[p]; } for(p = 0; p < 4; p++) /* on met à 0 les cases de temp correspondant aux 0 du code binaire de b */ { if (bb[p] == 0) temp[p] = 0; } /* on somme (OU EXCLUSIF) les cases de temp pour générer le résultat de la multiplication */ return temp[0] ^ temp[1] ^ temp[2] ^ temp[3]; } int expand_key(unsigned char key[4*4], unsigned char w[4*4*11]) /* effectue l'expansion de la clé ( key est la clé du chiffreur et w est la clé résultante - expanded key)
  • /
{ int i,j; unsigned char temp; for(i = 0; i < 16; i++) w[i] = key[i]; for(i = 16; i < 4*4*11; i++) { if (i % 16 < 4) { j = i % 4; if (j == 3) temp = w[i - 7]; else temp = w[i - 3]; temp = sub_s_box(temp, 'c'); if (i % 16 == 0) temp = temp ^ rcon(i/16); } w[i] = w[i - 16] ^ temp; } return 0; } int select_key(unsigned char expanded_key[4*4*11], unsigned char round_key[4][4], int round) /* applique simplement une partie de la expanded_key (du tableau du meme nom) a un round
  • /
{ int i,j; for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { round_key[j][i] = expanded_key[(round * 16) + (4 * i) + j]; } } return 0; } int byte_sub(unsigned char state[4][4], unsigned char cmd) /* effectue l'opération byte_sub
  • /
{ int i,j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if(cmd == 'd') state[i][j] ^= 198; //ajout du vecteur constant (décryptage) state[i][j] = sub_s_box(state[i][j], cmd); if(cmd == 'c') state[i][j] ^= 198; //ajout du vecteur constant (cryptage) } } return 0; } int shift_row(unsigned char state[4][4], unsigned char cmd) /* effectue l'opération shift_row
  • /
{ unsigned char temp; if (cmd == 'c') //cryptage { temp = state[1][0]; state[1][0] = state[1][1]; state[1][1] = state[1][2]; state[1][2] = state[1][3]; state[1][3] = temp; temp = state[2][0]; state[2][0] = state[2][2]; state[2][2] = temp; temp = state[2][1]; state[2][1] = state[2][3]; state[2][3] = temp; temp = state[3][3]; state[3][3] = state[3][2]; state[3][2] = state[3][1]; state[3][1] = state[3][0]; state[3][0] = temp; } else //décryptage { temp = state[1][3]; state[1][3] = state[1][2]; state[1][2] = state[1][1]; state[1][1] = state[1][0]; state[1][0] = temp; temp = state[2][0]; state[2][0] = state[2][2]; state[2][2] = temp; temp = state[2][1]; state[2][1] = state[2][3]; state[2][3] = temp; temp = state[3][0]; state[3][0] = state[3][1]; state[3][1] = state[3][2]; state[3][2] = state[3][3]; state[3][3] = temp; } return 0; } int mix_column(unsigned char state[4][4], unsigned char cmd) /* effectue l'opération mix_column
  • /
{ int i,j; unsigned char temp[4][4]; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) temp[i][j] = state[i][j]; } if (cmd == 'c') //cryptage { state[0][0] = multi(temp[0][0],2) ^ multi(temp[1][0],3) ^ multi(temp[2][0],1) ^ multi(temp[3][0],1); state[1][0] = multi(temp[0][0],1) ^ multi(temp[1][0],2) ^ multi(temp[2][0],3) ^ multi(temp[3][0],1); state[2][0] = multi(temp[0][0],1) ^ multi(temp[1][0],1) ^ multi(temp[2][0],2) ^ multi(temp[3][0],3); state[3][0] = multi(temp[0][0],3) ^ multi(temp[1][0],1) ^ multi(temp[2][0],1) ^ multi(temp[3][0],2); state[0][1] = multi(temp[0][1],2) ^ multi(temp[1][1],3) ^ multi(temp[2][1],1) ^ multi(temp[3][1],1); state[1][1] = multi(temp[0][1],1) ^ multi(temp[1][1],2) ^ multi(temp[2][1],3) ^ multi(temp[3][1],1); state[2][1] = multi(temp[0][1],1) ^ multi(temp[1][1],1) ^ multi(temp[2][1],2) ^ multi(temp[3][1],3); state[3][1] = multi(temp[0][1],3) ^ multi(temp[1][1],1) ^ multi(temp[2][1],1) ^ multi(temp[3][1],2); state[0][2] = multi(temp[0][2],2) ^ multi(temp[1][2],3) ^ multi(temp[2][2],1) ^ multi(temp[3][2],1); state[1][2] = multi(temp[0][2],1) ^ multi(temp[1][2],2) ^ multi(temp[2][2],3) ^ multi(temp[3][2],1); state[2][2] = multi(temp[0][2],1) ^ multi(temp[1][2],1) ^ multi(temp[2][2],2) ^ multi(temp[3][2],3); state[3][2] = multi(temp[0][2],3) ^ multi(temp[1][2],1) ^ multi(temp[2][2],1) ^ multi(temp[3][2],2); state[0][3] = multi(temp[0][3],2) ^ multi(temp[1][3],3) ^ multi(temp[2][3],1) ^ multi(temp[3][3],1); state[1][3] = multi(temp[0][3],1) ^ multi(temp[1][3],2) ^ multi(temp[2][3],3) ^ multi(temp[3][3],1); state[2][3] = multi(temp[0][3],1) ^ multi(temp[1][3],1) ^ multi(temp[2][3],2) ^ multi(temp[3][3],3); state[3][3] = multi(temp[0][3],3) ^ multi(temp[1][3],1) ^ multi(temp[2][3],1) ^ multi(temp[3][3],2); } else //décryptage { state[0][0] = multi(temp[0][0],14) ^ multi(temp[1][0],11) ^ multi(temp[2][0],13) ^ multi(temp[3][0],9); state[1][0] = multi(temp[0][0],9) ^ multi(temp[1][0],14) ^ multi(temp[2][0],11) ^ multi(temp[3][0],13); state[2][0] = multi(temp[0][0],13) ^ multi(temp[1][0],9) ^ multi(temp[2][0],14) ^ multi(temp[3][0],11); state[3][0] = multi(temp[0][0],11) ^ multi(temp[1][0],13) ^ multi(temp[2][0],9) ^ multi(temp[3][0],14); state[0][1] = multi(temp[0][1],14) ^ multi(temp[1][1],11) ^ multi(temp[2][1],13) ^ multi(temp[3][1],9); state[1][1] = multi(temp[0][1],9) ^ multi(temp[1][1],14) ^ multi(temp[2][1],11) ^ multi(temp[3][1],13); state[2][1] = multi(temp[0][1],13) ^ multi(temp[1][1],9) ^ multi(temp[2][1],14) ^ multi(temp[3][1],11); state[3][1] = multi(temp[0][1],11) ^ multi(temp[1][1],13) ^ multi(temp[2][1],9) ^ multi(temp[3][1],14); state[0][2] = multi(temp[0][2],14) ^ multi(temp[1][2],11) ^ multi(temp[2][2],13) ^ multi(temp[3][2],9); state[1][2] = multi(temp[0][2],9) ^ multi(temp[1][2],14) ^ multi(temp[2][2],11) ^ multi(temp[3][2],13); state[2][2] = multi(temp[0][2],13) ^ multi(temp[1][2],9) ^ multi(temp[2][2],14) ^ multi(temp[3][2],11); state[3][2] = multi(temp[0][2],11) ^ multi(temp[1][2],13) ^ multi(temp[2][2],9) ^ multi(temp[3][2],14); state[0][3] = multi(temp[0][3],14) ^ multi(temp[1][3],11) ^ multi(temp[2][3],13) ^ multi(temp[3][3],9); state[1][3] = multi(temp[0][3],9) ^ multi(temp[1][3],14) ^ multi(temp[2][3],11) ^ multi(temp[3][3],13); state[2][3] = multi(temp[0][3],13) ^ multi(temp[1][3],9) ^ multi(temp[2][3],14) ^ multi(temp[3][3],11); state[3][3] = multi(temp[0][3],11) ^ multi(temp[1][3],13) ^ multi(temp[2][3],9) ^ multi(temp[3][3],14); } return 0; } int add_round_key(unsigned char state[4][4], unsigned char round_key[4][4]) /* effectue l'opération add_round_key
  • /
{ int i,j; for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { state[i][j] ^= round_key[i][j]; } } return 0; } int round(unsigned char state[4][4], unsigned char round_key[4][4], int round, unsigned char cmd) /* effectue un round comprenant les 4 opérations (sauf le dernier qui ne contient pas mix_column)
  • /
{ if (cmd == 'c') { byte_sub(state, cmd); shift_row(state, cmd); if (round != 9) mix_column(state, cmd); add_round_key(state, round_key); } else { add_round_key(state, round_key); if (round != 9) mix_column(state, cmd); shift_row(state, cmd); byte_sub(state, cmd); } return 0; } int rijndael(unsigned char cmd, unsigned char data[16], unsigned char cipher_key[16]) /* effectue le cryptage ou le décryptage (selon la commande cmd) du bloc (data) avec la clé (cipher_key) passés en paramètres fonction appelée par le module de réception du système de transmission
  • /
{ int i, j; unsigned char state[4][4]; unsigned char expanded_key[11*16]; unsigned char round_key[4][4]; for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { state[i][j] = data[i * 4 + j]; } } expand_key(cipher_key, expanded_key); for(i = 0; i < 10; i++) { if (cmd == 'd') j = 9 - i; else j = i; select_key(expanded_key, round_key, j); round(state, round_key, j, cmd); } for(i = 0; i < 4; i++) { for(j = 0; j < 4; j++) { data[i * 4 + j] = state[i][j]; } } return 0; }

Conclusion :


Prochaine mise à jour: écriture de la même chose en C# et java. Disponible en Janvier 2004.
Pour l'utiliser, copier le code et faites en une procedure que vous appelerez.
Ou chercheez directement le code chiffrage de fichier.

A voir également

Ajouter un commentaire

Commentaires

Messages postés
2
Date d'inscription
vendredi 30 novembre 2012
Statut
Membre
Dernière intervention
14 mai 2013

j ai besoin le code source AES en c++builder qui crypte des textes
Messages postés
2
Date d'inscription
vendredi 30 novembre 2012
Statut
Membre
Dernière intervention
14 mai 2013

J AI BESOIN LE CODE SOURCE de AES
Messages postés
39
Date d'inscription
lundi 7 juin 2010
Statut
Membre
Dernière intervention
15 novembre 2011

ça compile pas ce code , une est erreur est produite qui est du à la commande
rijndael('c', texte, cle);
text ,'c' et cle sont de type char[] alors que les parametres de rijindael sont de type unsigned char . Comment la corrigées SVP ??
Messages postés
6
Date d'inscription
lundi 27 novembre 2000
Statut
Membre
Dernière intervention
17 août 2010

Bonjour,
Tout d'abord bravo pour le travail effectué. Une question me turlupine: il n'y a pas possibilité de choisir un IV ? Y en a-t-il un par defaut que je n'ai pas vu ?
Messages postés
215
Date d'inscription
mercredi 30 juillet 2003
Statut
Membre
Dernière intervention
25 septembre 2010

Puis-je ?

Je vais vous mettre tous les deux d'accord, ca vous intéresse ?
Il s'agit bien de puissance de 2, mais réalisées dans le corps fini de Gallois GF(2^8) (cite : "Rcon[i], contains the values given by [xi-1,{00},{00},{00}], with x i-1 being powers of x (x is denoted as {02}) in the field GF(28)" ---- source FIPS 197).
Voilà, donc il s'agit tout de même bien d'un 1B dans le vecteur (en fait 1B000000 même).

Sinon, il suffit d'utiliser les vecteurs Fips qu'on trouve sur le site du NIST pour valider une implémentation (et seulement l'implémentation, pas sa sécurité).
Afficher les 30 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.