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