Criptatore e Decriptatore con password generata

TheorLaw

Utente Iron
15 Maggio 2020
19
6
2
16
Salve!
Questo programma e' solo alla fase iniziale, ci ho messo poco a svilupparlo, conto di modificare ancora di piu' l'algoritmo per renderlo ancora più sicuro il testo.
Voglio generare tante parole quante la chiave ne ha , però il messaggio sarà nascosto in poche righe, cosi da rendere impossibile la decifrazione.
Devo ancora aggiungere l'input manuale, cosa che presto farò.
Comunque questo e' il programma.

C:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//---------- Macro ----------//
#define N 5000
//--------- Prototipo --------//
void Key_Random(FILE *);
int Check_File(FILE *,FILE *);
void Crypter(FILE *,FILE *,FILE *);
void Decrypter(FILE *,FILE *,FILE *);
//--------- MAIN ------------//
int main()
{
    //--------- Dichiarazione---------//
    srand(time(0));
    FILE *key,*crypted,*input,*decrypted;
    int check=0;
    //--------- Chiamata funzioni---------//
    Key_Random(key);
    check=Check_File(key,input);

    //--------- Controllo chiusura -------//
    if(check==404)
    {
        return 404;
    }
    //--------- Chiamata funzioni---------//
    Crypter(key,input,crypted);
    Decrypter(key,crypted,decrypted);



    return 0;
}
//-------- Funzioni --------//
void Key_Random(FILE *key)
{
    char reply;
    int key_random;
    //---------- Controllo key ----------//
    printf("Vuoi generare una chiave di %d caratteri Y/N : ",N);
    scanf("%c",&reply);
    if((reply=='n')||(reply=='N'))
    {
        return ;
    }
    //---------- Generatore key --------//
    key=fopen("key.txt","w");
    for(int i=0;i<N;i++)
    {
        if((i%2)==0)
        {
            key_random=rand()%94;
            key_random=key_random*(-1);
        }
        else
        {
            key_random=rand()%94;
        }
        fprintf(key,"%d\n",key_random);
    }
    printf("key.txt generato\n");
    fclose(key);
    return ;
}
int Check_File(FILE *key, FILE *input)
{
    //---------- Controlla se i file sono presenti ---------//
    if((key=fopen("key.txt","r"))==NULL)
    {
        printf("key.txt non trovato.");
        return 404;
    }
    if((input=fopen("input.txt","r"))==NULL)
    {
        printf("input.txt non trovato.");
        return 404;
    }
    fclose(key);
    fclose(input);
    return 0;
}
void Crypter(FILE *key,FILE *input,FILE *crypted)
{
    key=fopen("key.txt","r");
    input=fopen("input.txt","r");
    crypted=fopen("crypted.txt","w");
    //------ Imposta cursone a 0 ------//
    fseek(key,0,SEEK_SET);
    fseek(input,0,SEEK_SET);
    fseek(crypted,0,SEEK_SET);
    char key_x,input_x;
    //------- Criptatore -------//
    while(!feof(input))
    {
        fscanf(key,"%c",&key_x);
        fscanf(input,"%c",&input_x);
        input_x=input_x+key_x;
        fprintf(crypted,"%c",input_x);
    }
    fclose(key);
    fclose(input);
    fclose(crypted);
    printf("Testo cifrato.\n");
    return;
}
void Decrypter(FILE *key,FILE *crypted,FILE *decrypted)
{
    key=fopen("key.txt","r");
    crypted=fopen("crypted.txt","r");
    decrypted=fopen("decrypted.txt","w");
    //------ Imposta cursone a 0 ------//
    fseek(key,0,SEEK_SET);
    fseek(crypted,0,SEEK_SET);
    fseek(decrypted,0,SEEK_SET);
    char key_x,crypted_x;
    //------- Criptatore -------//
    while(!feof(crypted))
    {
        fscanf(key,"%c",&key_x);
        fscanf(crypted,"%c",&crypted_x);
        crypted_x=crypted_x-key_x;
        fprintf(decrypted,"%c",crypted_x);
    }
    fclose(key);
    fclose(crypted);
    fclose(decrypted);
    printf("Testo decifrato.");
    return;
}
Input
Codice:
Che rottura di palle, i miei figli.
crypted
Codice:
pž™*¤¢~¡©|”Pn–Qz˜v’dWsQs’žSp žv–cœ
 
Un piccolo consiglio: quando hai delle costanti che utilizzi per indicare degli stati (quali potrebbero essere gli errori), ti conviene sostituirle con delle costanti che facilitino la lettura del codice. Nel tuo caso ad esempio #define NOT_FOUND 404 e sotituire tutti i 404 del codice con NOT_FOUND . In questo modo la logica del programma e' di piu' semplice comprensione anche senza doverlo leggere tutto. Questa pratica ti tornera' utile quando i programmi saranno molto piu' complessi.
 
Mi permetto anche io di aggiungere alcune osservazioni/consigli.

Come dice @nostyn potresti codificare l'errore; a tal proposito preciso che le #define non sono costanti vere e proprie, in quanto elaborate dal preprocessore.
Detto ciò: l'errore è insolito darlo come 404, non essendo un applicativo web (di solito si utilizza un valore negativo, come -1).

C:
            key_random=rand()%94;
            key_random=key_random*(-1);

Se vuoi la chiave sia negativa è sufficiente che tu faccia key_random = -(rand()%94);

In teoria tutte le funzioni dovrebbero tornare un risultato sull'operazione svolta, e non stampare direttamente a schermo il risultato; quello dovrebbe farlo il chiamante.

Ultima cosa: ti consiglierei l'utilizzo di una convenzione nel nominare le variabili. Mi riferisco ad esempio a "key", che in realtà è l'handle al file.
In codici così brevi sono piccolezze, ma su codici più estesi quando leggi ad esempio "key", non sai se è una stringa o altro. Ad esempio io se è un handle utilizzo il prefisso h. Quindi sarebbe hKey (o meglio hKeyFile, o un nome più esplicativo).
 
  • Mi piace
Reazioni: nostyn
Ti voglio apportare un buon vecchio mantra della crittografia, Don't Roll Your Own Cryptography.
In genere sottolinea che nemmeno un crittografo qualificato dovrebbe scomodarsi provando a creare il proprio algoritmo crittografico at home, se non a scopo didattico. Prima di affermare che sia sicuro deve essere ben sperimentato attraverso considerevoli crittoanalisi e tanto altro, ma non voglio dilungarmi su questo (trovi più dettagli sul web).

C:
...
srand(time(0));
...
key_random=rand()%94;
...
Non ho testato il codice, ma appena ho visto queste righe ho deciso di smettere di leggerlo. Stai utilizzando il tempo time(0), o meglio i secondi come seed. Sapendo i secondi da cui hai generato la chiave, qualsiasi attaccante pratico a sufficienza riuscirebbe ad intercettare la tua "chiave" con pochissimi calcoli. rand() non genera numeri random ma pseudo-random (valori che sembrano casuali), quindi non è attendibile manco mezzo corno per l'utilizzo in algoritmi sicuri.
I PRNG (numeri pseudo-casuali), a differenza di quelli che generi, devono avere una entropia imponente. Ci sono diverse librerie che ne originano secondo criteri più avveduti, è un buon punto per iniziare.

È oggettivo che per le disposizioni di una buona sicurezza crittografica il tuo algoritmo è immediatamente bocciato. Ma ripeto, ciò non toglie che non sia male che tu lo abbia scritto ponendoti l'obiettivo di istruirti scrivendo qualcosa in C.
Se volevi scrivere qualcosa di utile per il forum potevi semplicemente far vedere come implementeresti un robusto algoritmo crittografico, ad esempio AES.