In questo articolo ti aggiornerò sull’Advanced Encryption Standard (AES), le modalità di blocco comuni, perché hai bisogno di padding e vettori di inizializzazione e come proteggere i tuoi dati dalla modifica. Infine vi mostrerò come implementare facilmente tutto questo con Java evitando la maggior parte dei problemi di sicurezza.
Cosa dovrebbe sapere ogni ingegnere software su AES
AES, conosciuto anche con il suo nome originale Rijndael, è stato selezionato dal NIST nel 2000 per trovare un successore del datato Data Encryption Standard (DES). AES è un cifratore a blocchi, cioè la crittografia avviene su gruppi di bit di lunghezza fissa. Nel nostro caso l’algoritmo definisce blocchi di 128 bit. AES supporta lunghezze di chiave di 128, 192 e 256 bit.
Ogni blocco passa attraverso molti cicli di trasformazione. Ometterò i dettagli dell’algoritmo qui, ma il lettore interessato è rimandato all’articolo di Wikipedia su AES. La parte importante è che la lunghezza della chiave non influenza la dimensione del blocco, ma il numero di ripetizioni dei cicli di trasformazione (la chiave a 128 bit è 10 cicli, 256 bit è 14)
Fino a maggio 2009, gli unici attacchi pubblicati di successo contro l’AES completo erano attacchi side-channel su alcune implementazioni specifiche. (Fonte)
Vuoi criptare più di un blocco?
AES cripta solo 128 bit di dati, ma se vogliamo criptare interi messaggi dobbiamo scegliere una modalità a blocchi con cui più blocchi possono essere criptati in un unico testo cifrato. La modalità a blocchi più semplice è Electronic Codebook o ECB. Utilizza la stessa chiave inalterata su ogni blocco in questo modo:
Questo è particolarmente brutto perché blocchi di testo in chiaro identici sono criptati in blocchi di testo cifrato identici.
Ricordatevi di non scegliere mai questa modalità a meno che non criptiate solo dati più piccoli di 128 bit. Sfortunatamente è ancora spesso usato impropriamente perché non richiede di fornire un vettore iniziale (di cui parleremo più avanti) e quindi sembra essere più facile da gestire per uno sviluppatore.
Un caso deve essere gestito con le modalità a blocchi però: cosa succede se l’ultimo blocco non è esattamente 128 bit? È qui che entra in gioco il padding, cioè il riempimento dei bit mancanti del blocco. Il più semplice dei quali riempie semplicemente i bit mancanti con degli zeri. Non c’è praticamente nessuna implicazione di sicurezza nella scelta del padding in AES.
Cipher Block Chaining (CBC)
Quindi quali alternative a ECB ci sono? Per esempio c’è la CBC che fa lo XOR del blocco di testo in chiaro corrente con il blocco di testo cifrato precedente. In questo modo, ogni blocco di testo cifrato dipende da tutti i blocchi di testo in chiaro elaborati fino a quel punto. Usando la stessa immagine di prima il risultato sarebbe un rumore non distinguibile dai dati casuali:
E allora il primo blocco? Il modo più semplice è usare un blocco pieno di zeri, ad esempio, ma poi ogni crittografia con la stessa chiave e lo stesso testo in chiaro darebbe come risultato lo stesso testo cifrato. Inoltre, se si riutilizza la stessa chiave per diversi testi in chiaro, sarebbe più facile recuperare la chiave. Un modo migliore è usare un vettore di inizializzazione casuale (IV). Questa è solo una parola di fantasia per dati casuali che sono circa la dimensione di un blocco (128 bit). Pensatelo come il sale della crittografia, cioè, un IV può essere pubblico, dovrebbe essere casuale e usato solo una volta. Ricorda però che non conoscere l’IV ostacolerà solo la decrittazione del primo blocco poiché il CBC XORs il testo cifrato e non il testo in chiaro del precedente.
Quando si trasmettono o persistono i dati è comune aggiungere semplicemente l’IV al messaggio cifrato attuale. Se sei interessato a come usare correttamente AES-CBC controlla la parte 2 di questa serie.
Modalità contatore (CTR)
Un’altra opzione è usare la modalità CTR. Questa modalità a blocchi è interessante perché trasforma un cifratore a blocchi in un cifratore a flusso, il che significa che non è richiesto alcun padding. Nella sua forma base tutti i blocchi sono numerati da 0 a n. Ogni blocco sarà ora criptato con la chiave, il IV (qui chiamato anche nonce) e il valore del contatore.