🔑 Crittografia

Numeri casuali in crittografia: perché la casualità conta

Chiavi, nonce e sali dipendono dalla casualità: generatori veri e pseudocasuali, fonti di entropia e cosa succede quando la casualità è debole.

Ogni chiave crittografica, ogni nonce, ogni sale e ogni valore temporaneo di uno scambio di chiavi nasce da un numero casuale. Se quel numero è prevedibile, anche il miglior algoritmo del mondo diventa inutile: l'attaccante non deve rompere AES o RSA, gli basta indovinare la chiave. Per questo la qualità della casualità è uno dei pilastri meno visibili, e più importanti, della crittografia.

Casuale non significa "che sembra casuale"

Una sequenza come 7, 3, 9, 1, 4 può sembrare casuale, ma in crittografia la domanda giusta è un'altra: può qualcuno prevedere il prossimo valore, o ricostruire quelli passati, osservando quelli che ha già visto?

Molti generatori di numeri inclusi nei linguaggi di programmazione producono sequenze statisticamente ben distribuite, perfette per simulazioni e videogiochi. Ma sono completamente determinate da uno stato interno: osservando un numero sufficiente di uscite, si può ricostruire quello stato e prevedere tutti i valori successivi. Per un gioco non è un problema; per una chiave crittografica è una catastrofe.

Due famiglie di generatori

Generatori veri

Un generatore di numeri casuali vero (TRNG) ricava i bit da fenomeni fisici imprevedibili: rumore elettronico nei circuiti, variazioni minime nei tempi di esecuzione, fenomeni quantistici. Molti processori moderni includono un generatore hardware di questo tipo. Il limite è che i fenomeni fisici producono bit lentamente e non sempre perfettamente uniformi.

Generatori pseudocasuali crittografici

Un generatore pseudocasuale crittograficamente sicuro (CSPRNG) parte da un piccolo seme realmente casuale e lo espande in una grande quantità di bit, usando costruzioni basate su cifrari o funzioni hash. La proprietà fondamentale è che, senza conoscere lo stato interno, le uscite sono indistinguibili da bit veramente casuali e non permettono di risalire ai valori precedenti o successivi.

Nella pratica i sistemi operativi combinano le due cose: raccolgono entropia da varie fonti fisiche, la mescolano in un insieme e la usano per alimentare un CSPRNG, che fornisce numeri casuali velocemente a tutte le applicazioni.

Dove si trova il generatore giusto

Il messaggio pratico è semplice: usa il generatore crittografico del sistema operativo, direttamente o attraverso la libreria crittografica che stai già usando.

Ambiente Fonte consigliata
Linux Chiamata di sistema getrandom o il dispositivo /dev/urandom
Windows Le funzioni di generazione casuale dell'interfaccia crittografica di sistema
macOS e iOS Le funzioni di generazione casuale sicura del sistema
Browser La funzione crypto.getRandomValues
Linguaggi di programmazione I moduli dedicati alla sicurezza, non le funzioni casuali generiche

Non serve, e anzi è controproducente, costruire un proprio generatore combinando orario, identificativo del processo e posizione del mouse.

Quando la casualità manca: casi reali

Gli errori di casualità hanno prodotto alcuni dei fallimenti crittografici più gravi.

  • Chiavi duplicate sui dispositivi: ricerche condotte analizzando milioni di chiavi pubbliche esposte su Internet hanno trovato numerosi dispositivi, soprattutto apparati di rete ed embedded, che condividevano chiavi o fattori primi. Molti generavano le chiavi al primo avvio, quando il sistema non aveva ancora raccolto abbastanza entropia.
  • Una modifica al codice che azzerò la casualità: nel 2008 si scoprì che in una nota distribuzione Linux, a causa di una modifica a una libreria crittografica, la casualità delle chiavi generate dipendeva quasi solo dall'identificativo del processo. Le chiavi possibili erano poche decine di migliaia e potevano essere elencate tutte.
  • Generatori sospetti negli standard: un generatore basato su curve ellittiche, inserito in uno standard statunitense, fu oggetto di forti sospetti per la possibile presenza di una "porta sul retro" legata ai suoi parametri. Nel 2014 fu ritirato dalle raccomandazioni ufficiali.
  • Nonce ripetuti nelle firme: diversi casi di compromissione di chiavi di firma ECDSA sono stati causati da valori che dovevano essere casuali e unici, ma non lo erano.

Situazioni a rischio

Alcuni contesti meritano attenzione particolare:

  • avvio dei sistemi: subito dopo l'accensione l'entropia può essere scarsa, soprattutto su dispositivi semplici senza tastiera, disco o generatore hardware;
  • macchine virtuali clonate: se si clona una macchina virtuale con lo stato del generatore già inizializzato, le copie possono produrre gli stessi valori;
  • dispositivi embedded e IoT: hanno poche fonti di rumore e spesso generano chiavi in fabbrica o al primo avvio.

I sistemi operativi moderni hanno migliorato molto la gestione di questi casi, per esempio bloccando la generazione finché il generatore non è stato inizializzato correttamente.

Casualità alla portata di tutti

Anche fuori dal codice la casualità conta. Una passphrase scelta "a caso" dalla mente umana tende a seguire schemi prevedibili. Metodi come estrarre parole da un elenco tirando dei dadi, oppure affidarsi al generatore di un buon gestore di password, producono segreti molto più robusti di quelli che inventiamo da soli.

In sintesi

  • Chiavi, nonce e sali sono sicuri solo se generati con una casualità imprevedibile.
  • I generatori casuali generici dei linguaggi non sono adatti alla crittografia.
  • I sistemi operativi raccolgono entropia fisica e la usano per alimentare un generatore crittografico sicuro.
  • Errori di casualità hanno causato chiavi duplicate, chiavi prevedibili e firme compromesse.
  • Usa sempre il generatore crittografico del sistema o della libreria, mai uno costruito in casa.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche