[C] Crittoanalisi di un cifrario amatoriale

di il
1 risposte

[C] Crittoanalisi di un cifrario amatoriale

Salve a tutti, per puro sfizio stavo cercando un modo semplice per migliorare un algoritmo di cifratura di un esercizio di informatica di qualche tempo fa, il quale testo diceva che la crittazione di una stringa avviene sommando ai suoi caratteri ascii quelli della chiave. Come è evidente il codice cosi ottenuto è vulnerabile a qualsiasi tipo di crittoanalisi.
Allora il miglioramento che propongo è dato dal seguente algoritmo che ho postato già in un altro forum ma a cui nessuno ha dato una risposta soddisfacente:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100000

long long int maiuscole(long long int lunghezza, char chiave[]);
long long int lettere(long long int lunghezza, char chiave[], long long int condizione);

int main(){
    long long int i;    /*Contatore*/
	char testo[MAX];	/*Testo in chiaro*/
	char chiave[MAX];	/*Chiave per cifrare*/
	char file[MAX];	    /*File scrittura cifra*/
	char r1[MAX];		/*Vettore cifrato scrittura*/
	char r2[MAX];		/*Vettore decifrato lettura*/
	char v1[MAX];		/*Vettore decifrato stampa*/
	char r3[MAX];		/*Di supporto, leggibilità algoritmo*/

	/*Dati per la cifratura*/
	printf("\nInserisci il testo da cifrare: ");
	getchar();
	fgets(testo, sizeof(testo), stdin);
	testo[strlen(testo) - 1] = '\0';

	printf("\nInserisci la chiave di cifratura: ");
	fgets(chiave, sizeof(chiave), stdin);
	chiave[strlen(chiave) - 1] = '\0';

	printf("\nInserisci il nome del file su cui salvare il testo cifrato: ");
	fgets(file, sizeof(file), stdin);
	file[strlen(file) - 1] = '\0';

	/*Cifratura*/
		for(i=0; i<strlen(testo); i++){
			r1[i] = testo[i] + chiave[i%strlen(chiave)];	/*Primo algoritmo*/
			}
		for(i=0; i<strlen(r1); i++){
				r1[i] = (r1[i] + lettere(strlen(chiave), chiave, i)) - maiuscole(strlen(chiave), chiave);
			}
	/*Testo cifrato*/
		FILE *fp;
		fp = fopen(file, "w");
		fprintf(fp, "%s", r1);
		fclose(fp);

	printf("\n\t***Crittazione avvenuta con successo***\a");
	printf("\n\t\t***Scrittura su file***");

	/*Decifratura*/
		for(i=0; i<strlen(r1); i++){
				r3[i] = (r1[i] - lettere(strlen(chiave), chiave, i)) + maiuscole(strlen(chiave), chiave);
			}
		r3[i] = '\0';
		for(i=0; i<strlen(r3); i++){
			v1[i] = r3[i] - chiave[i%strlen(chiave)];	/*Primo algoritmo*/
			}
		v1[i] = '\0';

	printf("\n\nIl testo decifrato e':\n\n%s\n", v1);
	printf("\n\t***Decrittazione completata con successo***\a\n\n");
	system("PAUSE");

	return 0;
    }


/*Definizioni*/
long long int maiuscole(long long int lunghezza, char chiave[]){
	long long int i, minuscola, maiuscola=0;
	for(i=0; i<=lunghezza; i++){
		if(64<chiave[i]<91){
			maiuscola++;
		}
	}
	minuscola = lunghezza - maiuscola;
	if(maiuscola == 0){
		return minuscola;
		}else if(minuscola>=maiuscola){
			return minuscola - maiuscola;
		}else{
			return maiuscola - minuscola;
		}
}


long long int lettere(long long int lunghezza, char chiave[], long long int condizione){
	long long int i, vocale=0, consonante=0;

	for(i=0; i<=lunghezza; i++){
		if(96<chiave[i]<123 || 64<chiave[i]<91){
			if(chiave[i]=='a' || chiave[i]=='A' || chiave[i]=='e' || chiave[i]=='E' || chiave[i]=='i' || chiave[i]=='I' || chiave[i]=='o' || chiave[i]=='O' || chiave[i]=='u' || chiave[i]=='U'){
				vocale++;
			}else{
				consonante++;
			}
		}
	}
	if(lunghezza%2 == 0){
		if(condizione%2 == 0){
			return (vocale + (lunghezza/2));
			}else{
				return consonante;
				}
	}else{
		if(condizione%2 == 0){
			return vocale;
			}else{
				return consonante + lunghezza;
				}
	}
}
La cifratura avviene sia nel main() con i cicli for, sia nelle funzioni; infatti nella funzione lettere(), che conta quante vocali e consonanti ci sono nella chiave, viene anche deciso quale valore ritornare in base proprio alle caratteristiche della chiave stessa (uguale per la funzione delle maiuscole). Speravo cosi di rendere più difficile un attacco sull'analisi statistica delle occorrenze tra caratteri, ma non sono proprio sicuro di aver risolto questo aspetto.
Sò che anche questo algoritmo non è completamente al sicuro dalla crittoanalisi, per esempio differenziale, e che aggiungere ulteriori elaborazioni che legano le caratteristiche della chiave al testo cifrato non fa altro che dare maggiori appigli nella possibile decodifica, se si conosce l'algoritmo di cifratura (principio di Kerckhoffs).

Vorrei sapere, avere un parere, a quali tipi di falle l'algoritmo migliorato ha messo una toppa e quali altre vulnerabilità si vengono a creare. Si può ulteriormente migliorare in modo altrettanto semplice cosi da avere un cifrario si amatoriale, ma neanche banale? Insomma qualcosa che non serva solo per cifrare le soluzioni sulla settimana enigmistica tipo ROT13

1 Risposte

  • Re: [C] Crittoanalisi di un cifrario amatoriale

    Nessuno?

    Con questo output non vedo niente di strano se non che nella prima codifica il testo cifrato è più corto di quello in chiaro:
    
    Testo: Questa è una prova per analizzare l'output della codifica.
    Cod:  œéÏëгû‘عՊèÎÁãÒ‘Ó°æŠÙʳÙÚëݬæϘÈyÜæåÓÀèŠÜÁ¾ÙґƺØÓÞŵΟ
    Chiave: Prova                                                     
                                                                      
    Testo: Questa è una prova per analizzare l'output della codifica.
    Cod:  žäÑæÒŒmùŒèÌŒmßÞâÔŒmßÑå~Œ»ÐØÜØ¥®áÑ“ÊR¼äàãÓŸmÓÑßÊŒmÒÛ×Ç‘¶ÒÍ¡
    Chiave: Prova.                                                    
                                                                      
    Testo: Questa è una prova per analizzare l'output della codifica.
    Cod:  ™å­Àß®húhÂÙ®hຼá®hà­¿‹®¶Ñ´¶åÇ©â­m×t·å¼½àÁhÔ­¹×®hÓ·±Ô³±Ó©{
    Chiave: LoL                                                       
                                                                      
    Testo: Questa è una prova per analizzare l'output della codifica.
    Cod:  ³ÚÅÞÖÆ€õ‚ÚÎÌ‚ÕÒÚØÆ€ÛÇ×€ÌÐÆÌÔÜßÁÝÇ…Ì’ÑÚÔÛ×Ù€ÏÇÑÌÌ‚ÈÏÏËËÉÎÓ
    Chiave: ciao
    
    Posso notare che i testi cifrati cambiano tantissimo anche con cambiamenti lievi della chiave immessa e che non è possibile, almeno mi pare, risalire al testo in chiaro attraverso l'analisi delle frequenze.
    L'unico dubbio è sulla lunghezza delle stringhe cifrate che non sempre sono della stessa lunghezza del testo in chiaro (ad un attaccante che non conosce niente sia del testo che della chiave non penso di avergli semplificato la vita con questa caratteristica, per uno che invece può fare analisi differenziali, cioè vedere come cambia un testo immettendo varie chiavi, potrebbe essere semplice perchè questo comportamento fa risalire ad una caratteristica della chiave e quindi alle altre, anche se ancora non ho ben capito quale).
Devi accedere o registrarti per scrivere nel forum
1 risposte