Funzioni di hash
Una funzione di hash , o message digest function, è una funzione che mappa un messaggio arbitrariamente lungo in una stringa di lunghezza prefissata, cercando di far in modo che da questa stringa non si possa risalire al messaggio che l'ha generata. La lunghezza della stringa finale è direttamente correlata con la sicurezza della funzione di hash, perché più una stringa è lunga, minore sarà la probabilità di trovare due messaggi con lo stesso digest, con la stessa stringa finale.
La stringa può essere vista come l'impronta digitale del messaggio, teoricamente irripetibile.
Ciò che si chiede da una funzione di hash è:
- l'efficienza computazionale, perché il messaggio potrebbe essere molto lungo;
- la probabilità che accada per un qualsiasi messaggio casuale deve essere , dove il digest è lungo bit.
- one way property o preimage resistance: dato il digest , dev'essere computazionalmente impossibile calcolare il messaggio che l'ha generato;
- dato il messaggio tale per cui , deve essere computazionalmente impossibile trovare un altro messaggio tale per cui ;
- deve essere computazionalmente impossibile trovare due messaggi ed che collidono, qualunque sia il loro digest.
Chiave delle funzioni di hash
modificaLe funzioni di hash possono essere con o senza chiave; se sono senza chiave, vengono chiamate Modification Detection Code (MDC), altrimenti sono chiamate Message Authentication Code (MAC).
Lo scopo degli MDC è garantire la protezione d'integrità dei dati, cioè garantire che il messaggio di cui si possiede il digest è proprio quello che si sta leggendo. Nel caso in cui si abbia a che fare con dei MAC, allora gli scopi sono non solo la protezione di integrità, ma anche l'autenticazione dell'autore del messaggio.
Nel caso dei MAC, si ha una chiave, quindi si ha
Possibili attacchi ad un MAC, oltre a quelli per gli MDC (che restano validi), possono essere:
- calcolare la chiave a partire da un numero sufficiente di digest ;
- conoscendo un sufficiente numero di , calcolare il corretto valore di senza conoscere la chiave;
- trovare due messaggi e tali per cui .
Se nel caso degli algoritmi di cifratura simmetrici lo scopo principale è fare in modo che il miglior modo di leggere un messaggio senza conoscere la chiave sia provare tutte le chiavi, nel caso degli algoritmi MDC lo scopo principale è fare in modo che trovare due messaggi che collidono significhi calcolare almeno hash, dove è la lunghezza dell'hash stesso.
Modification Detection Codes
modificaGli algoritmi MDC devono avere alcune proprietà, tra cui:
- preimage resistance, deve essere impossibile calcolare il messaggio a partire dal digest. Questa proprietà è importante, perché tra gli usi che si fa degli MDC c'è quello dell'autenticazione, dove l'utente si autentica al server mandando il digest
- dove la challenge è una stringa casuale di bit imposta dal server (cosa da non fare, è troppo pericolosa).
- weak collision resistance, deve essere impossibile, dato , trovare un messaggio tale per cui . Questo fatto è essenziale per le cosiddette firme digitali. Quello che si fa, infatti, è andare a firmare il digest del messaggio (che di solito è più corto del messaggio stesso), in modo tale da non rendere il calcolo della firma e la verifica un lavoro troppo oneroso per i calcolatori (pensiamo, ad esempio, al chip integrato in una smartcard, ha pochissima potenza computazionale). Se l'MDC non è sicuro da attacchi di questo tipo, allora sarà facile trovare un messaggio arbitrario che risulti esser stato firmato da qualcuno.
- strong collision resistance, deve essere impossibile trovare una qualsiasi coppia di messaggi ed che abbiano qualsivoglia digest . Questo fatto è importante perché l'attaccante potrebbe avere qualche potere sul messaggio da firmare; in questo caso, vale la regola che (se l'MDC è sicuro) la resistenza della funzione di hash è direttamente proporzionale alla lunghezza del digest.
- one-way property, deve essere impossibile ricavare il testo del messaggio a partire dal suo digest . Perché un MDC offra questa proprietà, ci deve essere una dimostrazione; ad oggi, non esiste alcuna dimostrazione che provi questa proprietà per nessun MDC usato, se non sotto certe ipotesi non sempre verificate; nonostante questo, può essere dimostrata la complessità computazionale minima per ricostruire il messaggio, dato il digest.
Funzioni di hash iterative
modificaQuello che si fa con le funzioni iterative è dividere il messaggio in blocchi e continuare a comprimere questi blocchi fino a raggiungere la lunghezza finale del digest.
La funzione di compressione lavora su bit, quindi servono iterazioni della funzione per avere il risultato in bit da dare alla trasformazione finale . La funzione è
dove il primo elemento è un vettore di inizializzazione , che può essere un valore predefinito (non deve essere casuale, altrimenti la funzione non sarebbe ripetibile), oppure una funzione del messaggio stesso.
Metodo Matyas-Meyer-Oseas
modificaIl metodo di Matyas, Meyer e Oseas prevede di sfruttare un algoritmo di cifratura a blocchi per costruire l'MDC. La funzione di compressione , quindi, sarà:
La funzione si occupa di creare la chiave per l'algoritmo di cifratura, a partire prima dall'IV e successivamente dal testo cifrato, occupandosi di ridurre o aumentare in maniera deterministica il numero di bit. La funzione di cifratura E_k sarà come quelle che abbiamo già visto nel capitolo dei criptosistemi simmetrici.
Questa soluzione non è la più adatta, visto che gli algoritmi di cifratura sono pensati per altri scopi e sono, di norma, meno efficienti di altri algoritmi progettati per costruire un MDC. Inoltre, la dimensione dell'hash sarà limitata dalla dimensione del blocco dell'algoritmo di cifratura: per esempio, col DES sarà di 64 bit.
Message digest 5
modificaL'algoritmo MD5 è stato pubblicato nel 1991 con l'RFC 1321, ed è il successore dell'MD4. Per questo protocollo
- il messaggio può avere qualsiasi dimensione;
- la lunghezza del digest è di 128 bit;
- la funzione di compressione lavora con blocchi di dati da 512 bit.
Per ovviare al fatto che il messaggio potrebbe non essere lungo esattamente un multiplo della dimensione del blocco , si ha un padding di questo tipo:
Quindi, il testo passato alla funzione di compressione è composto da
- il messaggio da proteggere;
- un bit a ;
- tanti quanto è necessario
- la lunghezza del messaggio, espressa in 64 bit. Da questo limite si ha che, se la lunghezza del messaggio è superiore, il numero contenuto in questo campo sarà espresso in modulo 64, cioè
Nell'algoritmo MD5 non è prevista la trasformazione finale , la funzione di compressione restituisce digest di 128 bit.
MD5 è molto veloce, ma la sua sicurezza sta diminuendo progressivamente. Nel 1996 è stato dimostrato che servono soltanto tentativi prima di trovare due messaggi che collidono, al posto di , cioè un numero molto più basso. Con un processore P4 a 1,6 GHz (quindi, alla portata di tutti) bastano 8 ore per trovare due messaggi che collidono.
$ md5sum qualsiasi_file
da cui si ottiene
- 318bde3b9a0fb0127d0864b6c2fa0ff1 qualsiasi_file
Secure Hashing Algorithm 1
modificaSHA-1 è un algoritmo MDC pubblicato nel 1993 con l'RFC 3174. Si ha:
- il messaggio deve essere lungo al massimo bit;
- il risultato del digest è lungo
- la dimensione del blocco della funzione di compressione è 512 bit.
SHA-1 è poco più lento di MD5, ma in compenso è considerato più sicuro. Oltre a SHA-1, esistono SHA-256, SHA-384 e SHA-512. Anche la sicurezza di SHA-1, come quella di MD5, sta scendendo. Ad oggi, sono necessari tentativi per trovare due messaggi che collidano (comunque, più del limite teorico di MD5), mentre dovrebbero essere
- .
$ sha1sum qualsiasi_file
da cui si ottiene
- bf7206323c6340aa269e75f7231544886611d59b qualsiasi_file
Ad oggi, MD5 è ancora molto usato. Usare SHA-1 è meglio che usare MD5, ma nel caso in cui si vogliano garanzie in più per il futuro, è meglio usare SHA-256 o superiori.
Performance degli MDC
modificaCon un processore P4 a 2,1 GHz, si riesce a calcolare la somma MD5 ad una velocità di
- 1716 Mbps con MD5;
- 609 Mbps con SHA-1;
- 409 Mbps con SHA-256;
- 186 Mbps con DES.
Message Authentication Codes
modificaUn algoritmo MAC può essere derivato da un MDC, semplicemente inserendo anche la chiave all'interno del messaggio che si va a firmare. Ci sono diversi approcci:
Chiave in coda al messaggio
modificaUsare questo approccio non è una buona idea. Supponiamo che un attaccante abbia a disposizione due messaggi che collidono con l'MDC, cioè esistono ed tali per cui
In questo caso, si avrà sicuramente
dal momento che la chiave viene usata soltanto all'ultima iterazione dell'algoritmo. A questo punto, all'attaccante basta convincere qualcuno a firmare il messaggio (cosa non difficile) per avere il messaggio firmato.
Chiave in testa al messaggio
modificaAnche in questo caso, non abbiamo il MAC ideale. Infatti, risulta molto facile ricavare il digest a partire da un digest , dove si ha , con un testo a piacere. Questo fatto non è immediatamente sfruttabile se l'MDC inserisce del padding, però è molto rischioso, non è sicuro.
Chiave in testa ed in coda ad un messaggio, MD5 envelope
modificaQuesto algoritmo è standardizzato dalla RFC 1828. Si tratta di usare l'algoritmo MD5 con
dove è il padding necessario per avere un messaggio che sia multiplo di 512 bit. La chiave viene usata sia all'inizio che alla fine dell'MD5, in modo tale che il suo effetto si faccia sentire su tutto il digest e non si possa aggiungere del nuovo testo in coda.
Per quanto riguarda le performance, sono pari ad MD5 e, quindi, ottime; il problema è che, con un sufficiente numero di coppie , un attaccante può arrivare a scoprire la . Questo fatto non è impossibile, visto che sia il digest (la firma) sia il messaggio firmato sono spesso disponibili su internet, pubblicamente. Ancora una volta, meglio non usare l'algoritmo MD5 envelope.
MAC basati su funzioni di hash
modificaCon la sigla HMAC si indicano tutte quelle funzioni MAC derivate da un algoritmo MDC secondo le specifiche dello standard RFC 2104. Si ha
dove le grandezze e sono delle costanti. La sicurezza di questo protocollo è stata dimostrata dagli autori, quindi l'attacco più efficace risulta essere proprio quello per tentativi.
- Trudy osserva un numero sufficiente di coppie , fin quando trova due messaggi con la stessa firma (collisione).
- Trudy calcola il messaggio e chiede ad Alice di firmarlo, in modo tale da ottenere
- Trudy è in grado di calcolare, senza conoscere la chiave , la firma
Questo attacco è possibile, ma impraticabile. Consideriamo di usare HMAC-MD5: Trudy dovrà memorizzare almeno blocchi da 512 bit, tutti generati con la stessa chiave. Si tratta di bit, cioè
- byte -> kB -> MB -> GB -> TB
Considerando una connessione a 10Gbps (cioè, 10 volte superiore alla velocità limite delle più moderne schede di rete cablate), servirebbero circa 25000 anni per avere il 50% di probabilità di successo. Quindi, HMAC è il MAC da usare, è dimostrato essere sicuro.
Collegamenti esterni
modifica- RFC 1321, algoritmo MD5 (in inglese) (5/12/2008 verificato funzionante)
- Elenco di attacchi che si possono compiere al protocollo MD5 (in inglese) (5/12/2008 verificato funzionante)
- RFC 3174, algoritmo SHA-1 (in inglese) (5/12/2008 verificato funzionante)
- RFC 1828, algoritmo MD5 envelope (in inglese) (5/12/2008 verificato funzionante)
- RFC 2104, algoritmi HMAC (in inglese) (5/12/2008 verificato funzionante)