Sei sulla pagina 1di 4

Elementi di crittografia: Gli algoritmi di hashing

di Maurizio Tarchini | 20 ott 2010 | in: Guide, Php, Sicurezza, Web

9 commenti

Non spaventarti, continua a leggere!


Ho esordito in questo modo in quanto vedere nello stesso titolo parole come crittografia e algoritmi di
hashing potrebbe intimorire.
Quello che in realtà voglio fare, in questa serie di articoli dedicati alla crittografia, è spiegare in modo
molto semplificato e comprensibile (non scriverò nessuna formula matematica, lo giuro) il
funzionamento e l’applicazione delle principali tecniche crittografiche. Alla fine sarai almeno in grado
di spiegare ai tuoi clienti perchè non devono aver paura ad utilizzare la carta di credito per fare acquisti
online (a determinate condizioni).
Gli argomenti che tratteremo saranno i seguenti:
 Algoritmi di hashing.
 Crittografia simmetrica.
 Crittografia asimmetrica.
Iniziamo con l’argomento di questo primo articolo ovvero gli algoritmi di hashing.

Mettiamo le stringhe nel tritatutto


In inglese to hash significa tritare la carne – pasticciare, praticamente fare delle polpette. Gli algoritmi
da hashing in effetti fanno proprio questo. Prendono una stringa di una qualsiasi lunghezza e producono
una stringa di una lunghezza definita (che varia a dipendenza del tipo di algoritmo) dalla quale non é
più possibile risalire alla stringa originale. Ma vediamo subito nella pratica cosa significa.
Per farlo prendiamo in considerazione un algoritmo molto utilizzato e conosciuto (anche se per molti é
superato) ovvero MD5. I principi che vedremo sono comunque validi per tutti gli algoritmi di hashing.
MD5 produce una stringa di 128 bit (32 caratteri) a partire da una stringa di lunghezza arbitraria.
Se passiamo “ciao” per MD5 otterremo questo hash
6e6bc4e49dd477ebc98ef4046c067b5f
Se vuoi fare delle prove, PHP mette a disposizione la funzione md5() il cui utilizzo è molto semplice:
echo md5("ciao");
Proviamo ora a passare l’intero contenuto di questo articolo a MD5, il risultato che otterremo sarà il
seguente:
fd2f23f583ab1ebf44952a744f65bd6e
Sempre una stringa di 32 caratteri.
Ed ora vediamo una cosa molto interessante: passiamo il contenuto di quello stesso articolo,
maeliminando la prima virgola dal testo.
Il risultato sarà questo:
cae3c5fd98e04344be0cd2ccecde0a44
Questo ci porta alla prima importante applicazione degli algoritmi di hashing. Un hash completamente
diverso solo per aver apportato una impercettibile modifica in una stringa lunghissima.

Checksum: evitare sorprese


Ti sarà certamente capitato, al download di un file, di trovare una scritta del genere
md5 checksum: cae3c5fd98e04344be0cd2ccecde0a44
Ebbene, a cosa serve?
Semplice. Chi mette a disposizione il file da scaricare, indica anche l’hash prodotto dall’applicazione di
MD5 su tale file.
Una volta scaricato il file, potrà essere nuovamente passato per MD5 e l’hash prodotto dovrà essere
identico. Se non lo è le cause possono essere due:
1. Durante il download è andata persa o corrotta una parte del file (è sufficiente anche un solo bit
come abbiamo visto).
2. Durante il download il file è stato intercettato e modificato (magari con l’aggiunta di codice
maligno).
In ogni caso, l’applicazione di questa tecnica ci mette al riparo da inutili rischi verificando l’integrità del
file che abbiamo scaricato.
Nel web si possono trovare molte applicazioni per calcolare l’hash MD5 di un file, ad esempio questa.

Conservare le password in modo corretto


Purtroppo mi capita spesso di vedere delle piccole applicazioni casalinghe (a volte anche professionali
(!)) nelle quali le password degli utenti sono salvate nel database così come sono, in chiaro. Questa è
una procedura sbagliata ed assolutamente da evitare. I motivi essenzialmente sono due.
1. L’eventuale violazione del database comporterebbe automaticamente la violazione delle
password di tutti i nostri utenti. In questo modo il malintenzionato potrebbe loggarsi
all’applicazione spacciandosi per qualunque utente (anche l’amministratore, perchè no). Inoltre
considera che la maggior parte delle persone utilizza la stessa password per accedere a tutto.
Dunque si tratterebbe di un’importante violazione della privacy dei nostri utenti.
2. Sempre per una ragione di privacy, non è corretto che chi ha accesso al database (anche
legittimamente) possa vedere le password degli utenti.
Per questa ragione, è necessario salvare le password passandole per un algoritmo di hashing. Dunque,
prima di salvare la password nel database, la passerò ad esempio per MD5.
Quando l’utente inserirà i suoi dati di accesso, passerò la password che ha inserito per MD5 e
confronterò la stringa prodotta con quella contenuta nel database.
In questo modo, anche se dovessi conoscere quanto contenuto nel campo password del database, non mi
servirebbe a nulla. Non potrei infatti risalire alla password originale e non potrei utilizzare quella stringa
come password, visto che al momento del login verrà passata per MD5 dando luogo ad una stringa
diversa.

Limiti e rimedi
All’inizio di questo articolo dicevamo che MD5 è considerato superato. Vi sono due principali motivi
alla base di questa affermazione:

Password deboli
Sappiamo che gli utenti utilizzano spesso delle password inadeguate, troppo comuni e banali. E
sappiamo anche che è facile trovare nel web dei grandissimi database contenenti le associazioni tra
stringa ed hash MD5.
Dunque se la mia password è “pippo”, il suo hash sarà:
0c88028bf3aa6a6a143ed846f2be1ea4
Ora prova ad inserire questo hash in uno dei tanti database, ad esempio questo.
Visto? Troppo facile!
Un possibile rimedio a questa debolezza è rendere la password dell’utente molto più complessa, e non è
necessario che lui lo sappia. Come?
Definiamo due costanti nel nostro file di configurazione:
define(“PRE_PASSWORD”, “#$[[a56?][*{00l45%!@wrv7”);
define(“POST_PASSWORD”, “Nel mezzo del cammin di nostra vita mi ritrovai in una
selva oscura, che la diritta via era smarrita. Ahi quanto a dir qual era è cosa
dura”);
Ora, quando salveremo la password, non ci limiteremo a passarla per MD5, ma anche a modificarla.
Dunque non utilizzeremo questa procedura:
$PasswordDaSalvare = md5($password);
Ma:
$PasswordDaSalvare = md5(PRE_PASSWORD . $password . POST_PASSWORD);
In questo modo la stringa “pippo” diventerà:
#$[[a56?][*{00l45%!@wrv7pippoNel mezzo del cammin di nostra vita mi ritrovai in una selva oscura,
che la diritta via era smarrita. Ahi quanto a dir qual era è cosa dura.
Che passata per MD5 darà questo hash:
8b1cc7082c7706a4929c8fc26e92a09e
Voglio vedere se la si trova in qualche database…
Naturalmente anche al login, quando l’utente inserirà “pippo”, prima di confrontarla con la stringa
salvata nel database, dovremo aggiungere PRE_PASSWORD e POST_PASSWORD e passare per
MD5.

Resistenza alle collisioni


In crittografia si parla di collisione quando un algoritmo di hashing produce lo stesso hash a partire da
due stringhe diverse.
Abbiamo visto che MD5 produce sempre una stringa di 128 bit. Dunque i possibili hash di MD5 sono
2128.
E’ un numero veramente astronomico, ma è comunque un numero finito. Le possibili stringhe in
entrata sono invece infinite in quanto non c’è un limite alla lunghezza che possono avere.
Possiamo concludere che vi è un numero teoricamente infinito di collisioni.
E’ per questa ragione che si parla di resistenza alle collisioni; Ovvero constatato che, a meno di limitare
la lunghezza delle stringhe in entrata, le collisioni ci saranno, deve essere perlomeno impossibile
individuarle. Dunque un algoritmo di hashing, per essere robusto, deve essere resistente alle collisioni.
Non deve essere quindi possibile individuare una procedura (o se individuabile deve essere
computazionalmente improponibile) che possa mettere in relazione due stringhe che producono lo stesso
hash.
In pratica se “pippo” da luogo a 0c88028bf3aa6a6a143ed846f2be1ea4, è possibile stabilire una
procedura grazie alla quale posso individuare un’altra stringa che mi produca lo stesso hash?
Teoricamente sì. Conosciamo l’algortimo MD5 e possiamo studiare le peculiarità della stringa “pippo”
che hanno portato a quell’hash.
Ma se la procedura che abbiamo individuato necessita dell’utilizzo di dieci super calcolatori per tre anni,
allora questa procedura è computazionalmente improponibile e quindi praticamente inutile.
Per molti, sulla resistenza alle collisioni, MD5 sta iniziando a mostrare la corda e il consiglio è di
utilizzare algoritmi della famiglia SHA.

Conclusione
In questo articolo abbiamo iniziato a calarci nell’affascinante mondo della crittografia. Spero di avere
trattato l’argomento in modo sufficientemente semplice visto che il tema è parecchio ostico. Nel
prossimo articolo vedremo i principi della crittografia simmetrica ovvero, per farla breve, come
scambiarsi messaggi segreti.
E tu, utilizzi gli algoritmi di hashing per conservare le password? Che algoritmo ritieni più sicuro?
Abitualmente verifichi l’hash dei file che scarichi (quando è disponibile)?

Potrebbero piacerti anche