Oggi ci addentriamo nel cuore della sicurezza informatica e della programmazione affrontando un tema tanto affascinante quanto cruciale: la crittografia simmetrica, conosciuta anche come crittografia a chiave privata.
Nel nostro percorso di apprendimento del linguaggio C, ci capita spesso di esplorare concetti informatici generali per poi declinarli a livello pratico scrivendo del codice. Oggi scopriremo cos’è la crittografia, esploreremo cifrari storici come quello di Cesare e di Vigenère e vedremo come implementare un algoritmo di cifratura sicuro direttamente in C.
Cos’è la Crittografia e perché ne abbiamo bisogno?
Immaginiamo di dover inviare un messaggio importante e di voler essere certi che, in caso di intercettazione, nessuno tranne il destinatario legittimo possa leggerlo. Che si tratti di un messaggero a cavallo con una lettera per Giulio Cesare o di un flusso di dati digitali su internet, la soluzione è l’offuscamento del testo.
La crittografia è proprio questo: un insieme di tecniche matematiche e logiche che trasformano un “testo in chiaro” (comprensibile a tutti) in un “testo cifrato” (incomprensibile). Oggi questa necessità non è relegata solo a scopi militari o industriali: ogni volta che navighiamo su un sito web protetto dal protocollo HTTPS, stiamo utilizzando la crittografia per difendere la nostra privacy e i nostri dati sensibili.
Crittografia a Chiave Privata: Come Funziona?
Esistono principalmente due grandi famiglie di crittografia: a chiave privata (simmetrica) e a chiave pubblica (asimmetrica).
Nella crittografia simmetrica, la regola d’oro è una sola: la chiave che chiude la serratura è la stessa che la apre. Esiste un’unica stringa segreta (che possiamo immaginare come una password) che viene utilizzata dall’algoritmo sia per cifrare il messaggio in partenza, sia per decifrarlo all’arrivo.
Dal Cifrario di Cesare al Cifrario di Vigenère
Il cifrario di Cesare è uno dei metodi più antichi: consiste nello scorrere ogni lettera del messaggio di un numero fisso di posizioni nell’alfabeto (ad esempio, spostandosi in avanti di 3 posizioni, la A diventa D, la B diventa E, e così via). Tuttavia, ha un enorme punto debole: l’analisi delle frequenze. In italiano, ad esempio, le vocali (soprattutto la “I”) appaiono molto spesso. Un attaccante può facilmente dedurre lo scostamento analizzando la frequenza delle lettere nel testo cifrato.
Per ovviare a questo problema, si è passati al Cifrario di Vigenère. Invece di usare uno scostamento fisso, questo algoritmo utilizza una “chiave testuale” che viene ripetuta per tutta la lunghezza del messaggio. Tramite una speciale matrice (la tavola di Vigenère), ogni lettera del testo in chiaro viene incrociata con una lettera della chiave segreta. In questo modo, la stessa lettera originale può essere tradotta in decine di caratteri cifrati diversi, rendendo l’analisi delle frequenze del tutto inefficace.
Implementare il Cifrario in Linguaggio C
L’aspetto più divertente per noi programmatori è trasformare questa logica in codice! Nel video tutorial implementiamo il Cifrario di Vigenère sfruttando le potenzialità del linguaggio C. Ecco alcuni dei passaggi chiave che abbiamo affrontato:
- Librerie standard utili: Sfruttiamo
<ctype.h>per utilizzare funzioni fondamentali comeisalpha()(per verificare se un carattere è una lettera),tolower()etoupper()per la gestione fluida di maiuscole e minuscole. - Aritmetica dei codici ASCII: Invece di memorizzare complesse matrici in memoria, possiamo calcolare matematicamente gli indici di sostituzione sottraendo o sommando il valore ASCII della lettera ‘A’ o ‘a’. È un metodo elegante e computazionalmente velocissimo!
- L’operatore Modulo (%): Per fare in modo che la chiave segreta (che di solito è più corta del messaggio) si ripeta ciclicamente senza uscire dai limiti della memoria (evitando fastidiosi segmentation fault), utilizziamo l’operatore modulo sull’indice della stringa.
- Gestione di file multipli: Come best practice di programmazione, abbiamo diviso il progetto in un file
.hper i prototipi delle funzioni e l’uso intelligente delle guardieifndef, e un file.cper l’implementazione logica vera e propria.
Il tallone d’Achille: Il problema della distribuzione della chiave
Nessun sistema è perfetto. Il più grande limite della crittografia simmetrica è il Key Distribution Problem (il problema della distribuzione delle chiavi). Se io e il mio destinatario dobbiamo usare la stessa identica chiave segreta, come faccio a comunicargliela senza che qualcuno la intercetti? Se il canale su cui invio la chiave viene compromesso, tutta la sicurezza dell’intero sistema crolla miseramente.
Inoltre, il mondo della crittografia deve oggi fare i conti con un futuro imminente: i computer quantistici, che in un domani non troppo lontano potrebbero avere la potenza di calcolo necessaria a “rompere” gran parte degli algoritmi di cifratura che oggi consideriamo sicuri, minacciando infrastrutture vitali e tecnologie come le criptovalute.
