Lezione di Crypting: comunicazione privata. La necessita' di proteggere l'informazione durante il trasferimento da un trasmettitore ad un ricevitore e' sempre stato un obiettivo ambito.  La storia stessa ci insegna che gia' in passato venivano utilizzati dei codici di trasmissione per occultare il significato del messaggio a terzi: a partire dai segnali di fumo dalle popolazioni indigene, codice morse... fino a sistemi piu' sofisticati che vennero introdotti durate la seconda guerra mondiale. Era quindi doveroso anche da parte nostra dedicare una sezione al cryptin` per darne una dimostrazione pratica. Premettendo che non sono un analista di questo problema, cerchero' di darvi un saggio su un semplice algoritmo che verra' utilizzato al fine di cryptare un messaggio di testo. Prima di procedere ci tengo a sottolienare che le routines che vi proporremo sono state scritte al solo scopo educativo, e sopratutto confidiamo nel fatto che voi possiate migliorarle dal momento che sono free. Un rigraziamento particolare va' a due miei cari amici... al mitico Lordfelix poiche' ha accettato di ascoltarmi per 2 ore durante l'approccio all'algoritmo... ed al grande Bazza che ha partecipato alla fase di debuggin`.     2-Way function.     Gli algoritmi di cryptaggio si suddividono in 2 classi: 1-way function e 2-way function. La differenza sostanziale tra i due gruppi sta' nel fatto che  i primi (1-way) sono processi irreversibili, mentre i secondi sono reversibili. Mostriamo qui di seguito uno schemetto per comprendere tale differenza.                       ---------                 |       |   messaggio --> | 1-way | --> messaggiocryptato   ????                 |       |                 ---------                       ---------                            ------------------                 |       |                            |                |   messaggio --> | 2-way | --> messaggiocryptato  --> | 2-way-reverse  | --> messaggio                 |       |                            |                |                 ---------                            ------------------         Se l'algoritmo e' una funzione 2-way possiamo costruire un filtro inverso in grado di restituire il messaggio originale. E' per questo motivo che i sistemi 1-way vengono utilizzati solo per l'autentificazione degli utenti in sistemi informatici, dove a priori e' nota l'informazione ( password dell'utente ). L'utente digita la password, questa viene cryptata secondo l'algoritmo, e confrontata con la password originale cryptata al momento della registrazione dell'utente: se le due pass cryptate coincidono, allora l'utente viene autorizzato. E' chiaro che il nostro interesse si pone sul secondo tipo di sistema. Stiamo cercando di realizzare un filtro numerico che ammetta il suo inverso in modo da poter costruire due routines: crypt e decrypt. L'algoritmo si basera' sostanzialmente su somme di convoluzione ( o correlazione ). La scelta e' stata dettata dai seguenti motivi: - Non sono un informatico e mi occupo piu' di fitri che di algoritmi che giocano con i bit. - E' un sistema dinamico in cui l'utente definisce il grado di complessita'.     Approccio alle somme di correlazione: vantaggi.   I vantaggi introdotti dalla somma di correlazione sono notevoli: facciamo un esempio pratico per illustrarli. Supponiamo di aver deciso di utilizzare un algoritmo poco intelligente il seguente: 'la stringa cryptata sara' il risutanto della somma (in byte) tra l'input e la key'. Vediamo il seguente schemetto. --------------------------------------------------------- 12 |45 |56 |23 |124| ... testo da cryptare --------------------------------------------------------- +    +    +    +   + --------------------------------------------------------- 5  | 5 |66 |23 |12 |  chiave. ---------------------------------------------------------   --------------------------------------------------------- 17 |50 | ....             testo cryptato --------------------------------------------------------- ...abbiamo deciso di fare le somme carattere per carattere... applicando il modulo 256 per non sforare dal set :) Cosa succede? Cerchiamo di fare una analisi statistica. Modelliamo la stringa in ingresso come un processo stocastico bianco A(n) distribuito secondo una certa legge. Della distribuzione di ciascun carattere non ne parleremo... senza ledere nella generalita' della dimostrazione... sceglieremo la gaussiana. Lo stesso facciamo con KEY(n). Adesso per semplificarci la vita poniamo che...   a(n)  =A(n) -   E{ A(n) } key(n)=KEY(n) - E{ KEY(n) } a(n) e key(n) sono adesso a valor medio nullo. La funzione di autocorrelazione  di a(n) e' pertanto... E{ a(k)a(n+k) }=Kronker(n)* potenza della sequenza.   ( ho indicato con E{} l'operatore lineare di aspettazione ) Considereremo pure i due processi indipendenti...   E{ key(k)key(n+k) }=Kronker(n) * potenza della chiave. Il cryptato risulterebbe, in buona approssimazione, una cosa tipo questa.. C(n)=a(n)+key(n)     per 0=N coincide con la seq. da cryptare.                                         - Key(n) per 0N-1 sequenza originale.                                       - C(n)   sequenza cryptata.     Non vi pare che ci stiamo dimenticando di qualcosa? Direi di si. La cosa interessante e' che tutte le relazioni che ho scritto per il filtro ed il suo inverso, restano vere anche se considero le equivalenze in modulo anziche' pure. Le seguenti relazioni ci vengono in auito... a=b+c e quindi a-b=c oppure... a=|modx b+c  da cui.....     a-b=|modx c     RFC del sorgente.     Il set di caratteri ASCII e' fissato a 256 valori. Utilizzero' nelle routines gli unsigned char perche' sono piu' buoni da trattare in quanto assumono solo valori positivi. In oltre dal momento che ci sono traumi notevoli sull'uso del char ascii 0 e 10 ho complicato un po' l'algoritmo rendendolo adatto alla sola cryptazione dei testi ascii ( ho limitato il set ASCII ). Dimenticatevi quindi di utilizzare le routines qui allegate per crytpare binari: il loro uso e' consentito se in ingresso viene posta una sequenza limitata in valore tra 1 e 254. Di default percio' assumo un set di caratteri compresi nel seguente range... 1 <=ASCII <=254  ( estremi inclusi.) Il char 0 e' il terribile terminatore di stringhe. Il char 255 viene utilizzato per rimappare il char 10 newline. Avrete a disposizione quindi 2 routines: conv e deconv da aggingere dei vostri sorgenti.   La conv e' in grando di cryptate + linee di testo in una sola stringa. La deconv e' il filtro inverso.   I prototipi delle due funzioni sono i seguenti.   char *conv (char *STRINGA_DA_CRYPTARE, char *COND_INIZIALE, char *KEY); char *deconv (char *STRINGA_DA_DECRYPTARE, char *COND_INIZIALE, char *KEY);   L'unica nota che possiamo mettere in evidenza e' il fatto che ci sono 2 stringhe KEY e CONDITION debbono essere note. In effetti si poteva fare a meno della cond. iniziale fissandola a priori, o addirittura estraendola da una parte della chiave stessa. Sono questi i migliromamenti che potete effetturare sul sorgente. Ripeto e' stato scritto al solo scopo educativo, pertanto e' giusto che le due stringhe siano differenziate vista la natura completamente diversa. NOTA IMPORTANTE: Non dimenticate che key e cond.iniziali debbono avere la stessa lunghezza!