2010-12-04 3 views
1

J'ai écrit un programme en C qui crypte les éléments d'une structure avec l'opération xor dans chaque caractère.Utilisation de l'opération xor pour chiffrer des éléments de structure

Lorsque j'utilise un mot de passe contenant des caractères non numériques, le code s'exécute normalement. Mais si le mot de passe contient des caractères numériques, les éléments de la structure ne sont pas entièrement imprimables. Voici le contenu du fichier (le nom du fichier est « entrée »):

500 
0 25 
5 
1 2 3 4 5 
6 7 8 9 10 
11 12 13 14 15 
16 17 18 19 20 
21 22 23 24 25 

Voici le code:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

//This structure stores the file data 
typedef struct arqc{ 
    char* npontos; 
    char* carta; 
    char* ordem; 
    char** matriz; 
}Arqc; 

int learq(Arqc* fp, FILE* arq); 
char criptografa(char ch, char chave); 
void decriptografa(Arqc* fp, char* chave, int tam_matriz); 

int main() 
{ 
    FILE* arq = fopen("input.txt","r"); 
    Arqc* fp; 
    int i; 
    int tam; 
    char* chave = "adr"; 
    fp = (Arqc*) malloc(sizeof(Arqc)); 
    if(fp == NULL) 
     exit(-1); 
    tam = learq(fp, arq); 
    decriptografa(fp, chave, tam); 
    puts(fp->npontos); 
    puts(fp->carta); 
    puts(fp->ordem); 
    for(i = 0; i < tam ; i++){ 
     puts(*(fp->matriz + i)); 
    } 

    decriptografa(fp, chave, tam); 
    puts(fp->npontos); 
    puts(fp->carta); 
    puts(fp->ordem); 
    for(i = 0; i < tam ; i++){ 
     puts(*(fp->matriz + i)); 
    } 

    for(i = 0; i < tam ; i++){ 
     free(*(fp->matriz + i)); 
    } 
    free(fp->npontos); 
    free(fp->carta); 
    free(fp->ordem); 
    free(fp); 
    fclose(arq); 
    return 0; 
} 

//read the file and stores it in a struct 
int learq(Arqc* fp, FILE* arq){ 
    int i = 0; 
    int tam; 
    int n; 
    int sair = 1; 
    char aux[101];//stores a string read from the file 
    /* *************************************************** */ 
    //this stretch every element of the struct will be filled 
    // with the characters in each line of the file 
    fgets(aux, 10, arq); 
    tam = strlen(aux); 
    fp->npontos = (char*) malloc(tam*sizeof(char)); 
    strncpy(fp->npontos, aux, tam - 1); 
    *(fp->npontos + tam - 1) = '\0'; 
    fgets(aux, 10, arq); 
    tam = strlen(aux); 
    fp->carta = (char*) malloc(tam*sizeof(char)); 
    strncpy(fp->carta, aux, tam - 1); 
    *(fp->carta + tam - 1) = '\0'; 
    fgets(aux, 10, arq); 
    tam = strlen(aux); 
    fp->ordem = (char*) malloc(tam*sizeof(char)); 
    strncpy(fp->ordem, aux, tam - 1); 
    *(fp->ordem + tam - 1) = '\0'; 
    /* ************************************************** */ 
    //read here is the character corresponding to the order of the matrix 
    //that is converted to the corresponding integer 
    n = atoi(fp->ordem); 
    //llocating the number of rows of the matrix 
    fp->matriz = (char**) malloc(n*sizeof(char*)); 
    while(sair){ 
     //while the file is not closed, the struct will receive the file data 
     if(fgets(aux, 101, arq) != NULL){ 
      tam = strlen(aux); 
      *(fp->matriz + i) = (char*) malloc(tam*sizeof(char)); 
      strncpy(*(fp->matriz + i), aux, tam - 1); 
      *(*(fp->matriz + i) + tam - 1) = '\0'; 
      i++; 
     } 
     else 
      sair = 0; 
    } 
//retorna a dimensão da matriz 
return n; 
} 

//criptografa cada caractere ch com um caractere chave 
char criptografa(char ch, char chave){ 
    ch = (ch&~chave)|(~ch&chave); 
    return ch; 
} 

//decrypts the file that was stored in fp using 'chave' to decrypt 
void decriptografa(Arqc* fp, char* chave, int tam_matriz){ 
    char aux[101]; 
    int i, j; 
    int n; 
    int tchave; 
    strcpy(aux, fp->npontos); 
    n = strlen(aux); 
    tchave = strlen(chave); 
    for(i = 0; i < n; i++){ 
     //decrypts each character read from the struct using the 'chave' characters 
     *(fp->npontos + i) = criptografa(*(fp->npontos + i), *(chave + i%tchave)); 
    } 
    strcpy(aux, fp->carta); 
    n = strlen(aux); 
    for(i = 0; i < n; i++){ 
     //decrypts each character read from the struct using the 'chave' characters 
     *(fp->carta + i) = criptografa(*(fp->carta + i), *(chave + i%tchave)); 
    } 
    strcpy(aux, fp->ordem); 
    n = strlen(aux); 
    for(i = 0; i < n; i++){ 
     //decrypts each character read from the struct using the 'chave' characters 
     *(fp->ordem + i) = criptografa(*(fp->ordem + i), *(chave + i%tchave)); 
    } 
    for(i = 0; i < tam_matriz; i++){ 
     strcpy(aux, *(fp->matriz + i)); 
     n = strlen(aux); 
     for(j = 0; j < n; j++){ 
      //decrypts each character read from the struct using the 'chave' characters 
      *(*(fp->matriz + i) + j) = criptografa(*(*(fp->matriz + i) + j), *(chave + i%tchave)); 
      printf("%c\n", *(*(fp->matriz + i) + j)); 
     } 
    } 

} 
+5

"Pas imprimable" - pourquoi souhaitez-vous imprimer le texte crypté? À toutes fins pratiques, il est binaire une fois qu'il a été crypté. –

+4

Et même si je n'ai pas lu votre code, il est très probablement très peu sûr. À moins que vous n'utilisiez un bon chiffrement de flux (ou un seul tampon) pour générer le flux de clés et ** ne jamais le réutiliser ** Le chiffrement Xor n'est pas sécurisé. En particulier, répéter le mot de passe et l'utiliser comme clé-flux n'est pas sûr. – CodesInChaos

+2

Je n'ai pas regardé de très près le code, mais en général, après le cryptage XOR, vous pouvez obtenir zéro octet dans la sortie. Cela signifie que l'utilisation de fonctions de chaînes (strcmp, strlen, strncpy, etc.) sur le texte crypté n'est pas correcte. – thkala

Répondre

4

Depuis que vous avez fourni le contenu de votre fichier d'entrée, je suis presque certain que le principal problème est votre utilisation des fonctions string.h et stdio.h orientées sur les chaînes de caractères sur le texte crypté. Pensez-y: votre fichier d'entrée est principalement composé de chiffres et votre mot de passe contient également des chiffres. Un caractère XOR'ed avec lui-même produira un octet zéro dont la plupart des fonctions C qui traitent des chaînes percevront comme la fin de la chaîne!

EDIT:

La façon de traiter cette question est d'accompagner chaque tampon avec un entier qui indique le nombre de caractères, et puis coller aux fonctions de manipulation de la zone mémoire tels que memcpy, memcmp etc Vous devriez également éviter * puts() et * gets() pour les E/S de fichiers, car celles-ci sont aussi orientées-chaînes.

EDIT 2:

Fondamentalement, vous devez traiter votre fichier d'entrée comme un fichier binaire avec un contenu inconnu, au lieu d'un fichier texte. Cela rendrait votre code plus robuste et polyvalent, mais cela signifie également que vous ne pouvez utiliser aucune des fonctions str *().

+0

Le problème n'est pas "" en soi - il utilise les mauvaises fonctions de ''. Plus précisément, utiliser 'fread()' et 'fwrite()' serait plus correct. –

+0

C'est vrai! il est probable que l'opération xor produise un caractère nul. Si je fais '1'xor'1' son produit un caractère nul qui indique la fin de la chaîne. – adriano

+0

@Jonathan Leffler: J'ai répondu plus clairement sur ce point, merci – thkala

Questions connexes