Aes: chiffrage et déchiffrage de fichiers

Contenu du snippet

Code qui implémente l'algorithme de chiffrage AES que j'ai aussi posté.
Il présente un méni que permet de faire des opérations de chiffrage, de déchiffrage, de calcul de taille,etc.

Le chiffrage se fait avec une clé de 128 bits qui est matérialisée par 16 caractères aléatoires que vous entrez au clavier.
Il possible de chiffrer n'importe quel type de fichier (.txt, .jpeg, .mpeg,etc...)

Bonne utilisation!

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
unsigned char rcon(int i)

	{
	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)

	{
	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;
		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;
		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;

	for (i = 0; i < 8; i++)
		{
		nb_1=0;
		do
			{
			if (temp[i] % 2 != 0)
				{
				temp[i] -= 1;
				nb_1++;
				}

			temp[i] /= 2;
			} while (temp[i]>0);

		r[i] = nb_1 % 2;
		}

	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)

	{
	int bb[5] = {0,0,0,0,0}, p = 0, intemp;
	unsigned char temp[5];
	temp[0] = b;

	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 < 5; p++)	//on considére b de la forme 0x ou 1x
			{
			intemp = temp[p] * 2;
			if (intemp > 255) temp[p] = (intemp - 256) ^ 27;
			else temp[p] = intemp;
			if (p < 4) temp[p + 1] = temp[p];
			}

	for(p = 0; p < 5; p++)
			{
			if (bb[p] == 0) temp[p] = 0;
			}

	return temp[0] ^ temp[1] ^ temp[2] ^ temp[3] ^ temp[4];
	}

int expand_key(unsigned char key[4*4], unsigned char w[4*4*11])

	{
	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)

	{
	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)

	{
	int i,j;

	for (i = 0; i < 4; i++)
		{
		for (j = 0; j < 4; j++)
			{
			if(cmd == 'd') state[i][j] ^= 198;
			state[i][j] = sub_s_box(state[i][j], cmd);
			if(cmd == 'c') state[i][j] ^= 198;
			}
		}

	return 0;
	}

int shift_row(unsigned char state[4][4], unsigned char cmd)

	{
	unsigned char temp;

	if (cmd == 'c')
		{
		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
		{
		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)

	{
	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')
		{
		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
		{
		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]) // penser a faire key selection et passer d'un tab 1n a 11 tab 44

	{
	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)

	{
	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])

	{
	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;
	}
int* taille_fichier(char *fic_quelq,int *table)//prgm qui donne le nombre de trames de  bits et le nombre d'octet de la dernière trame
{       //le tableau table contient en son indice 0 le nombre de trame de 128 bits et en son indice 1
        //le nombre d'octet de la deniere trame qui, elle ne fait pas toujours 16 octets
        void* p_lecture;
	FILE* desc_quelq;
     
	p_lecture = (void*)malloc(16); //tableau d'un paquet de 16 octets
	if(desc_quelq = fopen(fic_quelq,"rb"))
	{       while(( table[1] = fread(p_lecture,1,16,desc_quelq)) != 0) //lecture de 16 objets de 1 octet
		{       if(table[1]< 16 )
                        {      fclose(desc_quelq);
                               return table;
                        }                           
			table[0] ++;
		}
		fclose(desc_quelq);
                return table;
	}
	else
	{       printf("\nLe programme d'ouverture du fichier a rencontré un probleme et doit fermer.\nVeuillez le fermer et relancer  l'operation\n");
		free(p_lecture);
                return table;
	}
}
void gen_fic(char* nouv_fic,char* fic_quelq,int *table)//une procedure pour generrer le fichier qui
{                                                      //sera envoyé à l'uart.
        FILE *desc_nouv,*desc_quelq;
        void *p_lecture = NULL;
        p_lecture =(void*) malloc(16);
        desc_nouv = fopen(nouv_fic,"wb");
        desc_quelq = fopen(fic_quelq,"rb");
        
        if((desc_nouv!= NULL) && (desc_quelq !=NULL))
        {       fwrite(table,sizeof(int),2,desc_nouv);//ecriture de la taille du fichier à crypter
                fwrite(p_lecture,1,16-2*sizeof(int),desc_nouv);//la premiere trame vaut 128 bits
                while( (table[1] = fread(p_lecture,1,16,desc_quelq)) != 0)
                {       fwrite(p_lecture,1,16,desc_nouv);
                }
                fclose(desc_nouv);
                fclose(desc_quelq);
        }
        else
        {       printf("\nLe programme d'ouverture du fichier à crypter a rencontrer un problème et doit fermer.\n Veuillez le fermer et relancer la procedure.\n");
        }
}

void  lecture_fichier(char *file_send,char *file_received,char cmd,char *key)
{       //lit le fichier à envoyer à l'uart et crée un fichier pour stocker les trames qui 
        //viennent de l'uart , traitées ,envoie data, key et cmd à code_ip() pour crypter ou décrypter
        FILE *desc_send,*desc_received;
        char *p_lecture = NULL;
        p_lecture = (char*)malloc(16);//trame de 128 bits
        int nbr;
        desc_send = fopen(file_send,"rb");
        desc_received = fopen(file_received,"wb");
         if((desc_send!= NULL) && (desc_received !=NULL))//bonnes ouvertures de fichiers
         {      //fread(table,sizeof(int),2,desc_send);
                //printf("\nLes tailles recupérées sont de %d trames de 128 bits et de %d octets dasn la dernière trame",table[0],table[1]);
                //fseek(desc_send,SEEK_SET,16);//on se place à partir de la seconde trame
                //fwrite(table,sizeof(int),2,desc_received);//écriture dans le fichier reçu de l'uart de la taille du fichier de départ.
                //fwrite(p_lecture,1,16-2*sizeof(int),desc_received);//la premiere trame vaut 128 bits
                while((nbr = fread(p_lecture,1,16,desc_send)) != 0)
                        {rijndael(cmd,p_lecture,key);//cryptage
                        fwrite(p_lecture,1,16,desc_received);//écriture dans le fichier de reception
                        }
               fclose(desc_send);
               fclose(desc_received);
         }
         else
         {printf("\nLe programme d'ouverture du fichier à crypter a rencontrer un problème et doit fermer.\n Veuillez le fermer et relancer la procedure.\n");
         }

}

void gen_fic_quelq(char *nouv_fic,char *fic_quelq2)//géneration du fichier de départ à partir du fichier qui a un nombre entier de trames de 128 bits
{       int i;
        int tableau[3];//le tableau de lecture de la taille du fichier de depart
        tableau[0]=0;tableau[1]=0;//initialisation
        FILE *desc_nouv,*desc_quelq2;
        void *p_lecture =  NULL;
        
        p_lecture = (void*)malloc(16);
        desc_nouv = fopen(nouv_fic,"rb");
        desc_quelq2 = fopen(fic_quelq2,"wb");
        if((desc_nouv!= NULL) && (desc_quelq2 !=NULL))
        {       fread(tableau,sizeof(int),2,desc_nouv);//lecture de la taille du fichier
                fseek(desc_nouv,16,SEEK_SET);//saut des octets non significatifs
                for(i=0;i<tableau[0];i++)
                {       fread(p_lecture,1,16,desc_nouv);
                        fwrite(p_lecture,1,16,desc_quelq2);//lecture des blocs de 128 bits
                }
                fread(p_lecture,1,tableau[1],desc_nouv);
                fwrite(p_lecture,1,tableau[1],desc_quelq2);//ecriture de la partie significative de la dernire trame
                fclose(desc_quelq2);
                fclose(desc_nouv);
        }
        else
        {        free(p_lecture);
                 printf("\nLe programme d'ouverture du fichier à crypter a rencontrer un problème et doit fermer.\n Veuillez le fermer et relancer la procedure.\n");
        }
}

int main()
{       int table[3];
	int *lonfic2;
	char *fic_quelq,*nouv_fic,*fic_arrive,*fic_decrypte_recu,*dossier,key_temp [255],msg[]= "\nTapez 16 caractères correspondant à la clé de cryptage :\n";
        unsigned char key[17];
	int choix_menu,i,tours = 0;
        char cmd;
        printf("\n\tSoyez la bienvenue dans MINMOUCRYPT, le nouveau logiciel de cryptage\n\t qui apporte une confidentialité sans failles à vos données!!!\n\n");
        fic_quelq = (char*)malloc(60*sizeof(char));
        nouv_fic = (char*)malloc(60*sizeof(char));
        fic_arrive = (char*)malloc(60*sizeof(char));
        fic_decrypte_recu = (char*)malloc(60*sizeof(char));
        do{     printf("\n%s",msg);//saisie de la clef
                gets(key_temp);
                fflush(stdin);
                strcpy(msg,"Saisie incorrecte. Veuillez recommencer:\n");
        }while( strlen(key_temp)!= 16);
        strcpy(key,key_temp);//copie de la clef temporaire dans la definitive.
       do{
        table[0]=0; table[1]=0; //inintialisations de table        
        if(tours<1)
        {       printf("\n\tTapez le nom du fichier de départ:\t");
                fflush(stdin);
                scanf("%s",fic_quelq);
         
                printf("\n\tTapez le nom du fichier d'arrivée:\t");
                fflush(stdin);
                scanf("%s",fic_arrive);
        }
        strcpy(nouv_fic,"fic_gen.mm");//le fichier a transmettre qui a un nombre entier de trame de 128 bits
        strcpy(fic_decrypte_recu,"fichier_recu2.mm");//le fichier reçu de l'uart decrypté
                printf("---------------------------- MENU DES OPERATIONS--------------------------\n\n\n");
                printf("\t\t1- Calculer la taille du fichier à traiter\n");
                printf("\t\t2-Crypter le fichier de départ\n");
                printf("\t\t3-Décrypter le fichier de départ\n");
                printf("\t\t4-Changer de fichiers de départ et d'arrivée\n");
                printf("\t\t5-Crédits\n");
                printf("\t\t6-Quitter\n");
                printf("\n\tVeuillez taper votre choix:\t");
                fflush(stdin);
                scanf("%d",&choix_menu);
                lonfic2 =  taille_fichier(fic_quelq,table);
                switch(choix_menu)
                {       case 1: printf("\nLe nombre de paquet de 128 bits est de : \t%d \nle nombre d'octet de la derniere trame est de: \t%d\n",lonfic2[0],lonfic2[1]);    
                        break;
                        case 2: gen_fic(nouv_fic,fic_quelq,lonfic2);
                                lecture_fichier(nouv_fic,fic_arrive,'c',key);
                                printf("\nLe cryptage est terminé!!!!\n");
                        break;
                        case 3: lecture_fichier(fic_quelq,fic_decrypte_recu,'d',key);
                                gen_fic_quelq(fic_decrypte_recu,fic_arrive);
                                printf("\nLe décryptage est terminé!!!!\n");
                        break;
                        case 4:tours = -1;
                        break;
                        case 5: printf("\n\tMINMOUCRYPT, logiciel de cryptage/decryptage de données\n\tutilisant le nouveau puissant standard de cryptage AES.\n\t");
                                printf("Le cryptage et le decryptage utilisent l'algorithme de Rijndael.\n\tLa clé de cryptage a une longueur de 128 bits.");
                                printf("\n\tToutes modifications, utilisations publiques et autres actions \n\trepréhensibles sur ce logiciel sont interdites.\n\t");
                                printf("Et par conséquent feraient l'objet de poursuites judicaires si\n\telles sont constatées.\n");
                        break;
                        case 6: printf("\nMerci de nous faire confiance et d'avoir choisi MINMOUCRYPT");
                        break;
                        default:printf("\nCe choix ne convient pas. Veuillez saisir à nouveau votre choix\n\n");
                }
                tours++; 
       }while(choix_menu != 6);
        free(fic_arrive);
        free(fic_quelq);//liberation de memoire
        free(nouv_fic);
        free(fic_decrypte_recu);
        //free(fichier_crypte);
        return 0;
}

Conclusion :


Règle N°1: Ne jamais promettre....enfin vous devez savoir!
++

A voir également

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.