Sicurezza IIProf. Dario Catalano
Errori di Implementazione
Introduzione
Abbiamo fatto una (breve) carrellata di tecniche crittografiche utili alla sicurezza.
E’ opportuno discutere alcuni usi sbagliati (e frequenti) di tali metodi.
I 5 comandamenti
1. Usare solo primitive crittografiche ben studiate (es. AES)
2. Quando possibile, limitarsi a metodologia dimostrabilmente sicure.
3. Non assumere che una data costruzione abbia proprieta’ che non sono quelle per le quali essa e’ stata progettata.
I 5 comandamenti (cont.)
4. Il fatto di utilizzare primitive singolarmente sicure non implica la sicurezza dell’intero sistema.
5. Fare in modo che la propria implementazioni realizzi esattamente lo schema per il quale conosciamo una dimostrazione.
Utilizzo di costruzioni senza prova di sicurezza. Molti schemi non hanno una
dimostrazione di sicurezza. L’abitudine di dimostrare la sicurezza dei
sistemi simmetrici ha cominciato a diffondersi solo a partire dai primi anni 90.
Oggi si comincia (finalmente) a capire l’importanza delle dimostrazioni.
Nonostante cio’ capita ancora abbastanza spesso di vedere utilizzati schemi insicuri. Es ECB
Utilizzare il tool sbagliato Errore comunissimo: utilizzare
encryption per fare authentication. E’ estremamente rischioso
utilizzare una primitiva nel constesto sbagliato.
Utilizzare un schema dimostrabilmente sicuro non vuol dire che tale scheme garantira’ qualsiasi proprieta’ di sicurezza.
Utilizzare il tool sbagliato (cont)
Molti schemi sono stati attaccati perche’ gli ideatori assumevano che encryption garantisce anche auth. MAC non erano parte integrante delle
prime specifiche di IPsec Cio’ ha reso IPsec vulnerabile a determinati
attacchi. La prima versione di SSH non utilizzava
MAC
Implementazioni imprecise
A volte anche una piccola variazione su un sistema dimostrabilmente sicuro, puo’ condurre a conseguenze catastrofiche.
Ricordiamoci che la sicurezza di un sistema dipende sempre dalla sicurezza della sua componente piu’ debole.
Implementazioni imprecise (cont)
Gli esempi pratici non mancano. La Diebold (costruiva macchine per
fare e-voting) utilizzava, nei propri prodotti, una variante di CBC$ (CBC0)
Tale variante rendeva CBC$ completamente insicuro.
Vediamo perche’
Numeri casuali I numeri casuali svolgono un ruolo
di fondamentale importanza in crittografia. Generazione della chiave,
generazione di crittotesti, etc. E’ dunque importante anche
essere in grado di generarli correttamente.
Riguardiamo CBC$
CBC$: come interpretare il codice?
• Non tutto e’ facilmente interpretabile (ed implementabile), da un non esperto di crittografia.
I problemi da affrontare
Primo problema: come fa un computer (deterministico) a generare numeri casuali? Dobbiamo necessariamente
accontentarci di numeri pseudo casuali. Secondo problema: come generare
numeri pseudo casuali in C o Java?
Il generatore C
Le librerie C contengono due funzioni (rand e srand) che permette di generare numeri pseudo casuali.
srand prende in input un seme seed e inizializza il generatore rand.
Il generatore C (cont)
function srand(seed) state=seed;
function rand()state=((state*1103515245)+12345)
mod 231;return state
Usare il generatore Supponiamo di voler utilizzare tale
generatore per generare una chiave AES (128 bit).
E’ chiaro che non possiamo utilizzare un solo output del generatore Avremmo solo 32 bit
Possiamo pensare di concatenare piu’ output.
Usare il generatore (cont)
function AES-KeyGen()key[0]=rand(); key[1]=rand();key[2]=rand(); key[3]=rand();return key.
In questo modo otteniamo una chiave di 128 bit come richiesto.
Il sistema sembra funzionare perfettamente…
Eppure…
Poiche’ state=((state*1103515245)+12345) mod 231
key[1]=((key[0]*1103515245)+12345) mod 231
key[2]=((key[1]*1103515245)+12345) mod 231
=((((key[0]*1103515245)+12345)*1103515245)+12345) mod 231
In sostanza tutte le componenti sono generate da key[0] in modo facilmente riproducibile.
Anche se la chiave e’ di 128 bit esistono solo 232 possibilita’.
Ulteriori problemi Esistono altri due problemi con la
funzione rand()1. Il seme e’ di soli 32 bit.2. Conoscendo un valore di state e’
possibile calcolare il successivo. Un approccio alternativo potrebbe
essere quello di creare numeri casuali utilizzando AES (o SHA1)
Netscape 1.1 random number generator
Osservazioni
In linea di principio non possiamo piu’ ricavare il seme x facilmente x e’ 160 bit Al primo utilizzo riveliamo solo
SHA1(x) Il fatto di utilizzare buone primitive
crittografiche, e’ sufficiente a garantire sicurezza?
Osservazioni (cont)
Sfortunatamente no! La chiave dipende essenzialmente
da pid, ppid e il tempo. Se l’avversario potesse accedere a
tali info tutta la sicurezza del sistema crollerebbe.
Non considerare la sicurezza dell’intero sistema. Supponiamo di voler garantire
autenticita’ e privacy allo stesso momento.
Idea: prima cifro il messaggio e poi lo autentico. Quindi invio al destinatario sia il crittotesto che il tag prodotto.
Non c’e’ motivo per cui un tale approccio non debba funzionare, no?
Non considerare la sicurezza dell’intero sistema (cont) Tale approccio puo’ non funzionare in
pratica. Il problema e’ che MA non si cura di
privacy ed encryption non si cura di MA. Esempio classico: combinare CBC$
encryption e CBC-MAC. CBC-MAC e’ deterministico e rivela
informazioni sul messaggio autenticato.
CBC MAC
Conclusioni
Realizzare sistemi sicuri e’ molto difficile.
Bisognerebbe sempre muoversi con i piedi di piombo.