La risposta in breve? usate bcrypt.

Esistono moduli per cifrare/decifrare una stringa in bcrypt per python, node.js, ruby, erlang, php e praticamente quasi ogni altro linguaggio conosciuto.

Perchè non usare {MD5, SHA1, SHA256, SHA512, SHA-3, etc.} ?

Queste sono tutte funzioni di hashing general-purpose, pensate per calcolare un hash di una mole corposa di dati nel più breve tempo possibile. Questo vuol dire che sono fantastici per assicurare l’integrità dei dati, ma terribili per storare una password.

Un server moderno può calcolare l’hash MD5 di un file da 330 MB in 1 secondo. Se i vostri utenti hanno password che sono composte da soli sei caratteri minuscoli, allfanumerici, si può provare qualunque combinazione possibile di quella lunghezza e arrivare alla password in chiaro in circa 40 secondi.

E questo senza investire nulla. Se volessimo spendere 2000 dollari e avessimo una settimana di tempo, potremmo mettere assieme un cluster di supercomputer con una potenza di calcolo di circa 700.000.000 password al secondo. A questo rate le password sopra verrebbero forzate in meno di 1 secondo.

L’aggiunta del Salt non aiuta

E’ importante notare come l’uso del salt nelle password sia del tutto inutile contro attacchi di tipo dizionaro o forza bruta (brute force).

Potete usare un salt lungo, con un livello di entropia altissimo o il sale dell’Himalaya. Non ha alcun impatto sulla velocità con un cui un hacker può provare la pass candidata, dato l’hash e il salt contenuto nel vostro database.

Salt o meno, se usate una funzione di hashing general-purpose, progettata per essere veloce, siete vulnerabili.

bcrypt risolve il problema

Come? Beh, sostanzialmente è lento di brutto. Usa una variante dell’algoritmo crittografico Blowfish e introduce un fattore lavoro (work factor), che ti permette di determinare quanto “costosa” sarà la funzione di hashing. A causa di questa caratteristica può restare al passo con la legge di Moore. Man mano che i computer diventano più veloci, ci basta aumentare il work factor e l’hashing sarà più lento.

Quanto è lento bcrypt paragonato a MD5? Dipende dal work factor. Usando per esempio un work factor di 12, bcrypt calcola l’hash della parola ciao in circa 0.3 secondi. MD5 invece impiega meno di un microsecondo.

Quindi parliamo di 5 ordini di grandezza. Invece di craccare una password ogni 40 secondi, nè craccherei una ogni 12 anni circa.
Magari la vostra password non richiede un livello di sicurezza del genere, e in alcuni casi è preferibile un algoritmo che abbia tempi di comparazione più rapidi. In ogni caso bcrypt permette di scegliere il giusto bilanciamento fra sicurezza e velocità.

FAQ

bcrypt non è semplicemente Blowfish?

bcrypt è un algoritmo di hashing adattabile che usa il keying schedule di Blowfish, non è un algoritmo simmetrico.

Hai detto che il salt non è utile, e allora le rainbow table?

bcrypt integra già un sistema di salting per prevenire gli attacchi basati su rainbow-table. Non stiam dicendo che non ha senso usarlo. Stiam dicendo che non ha senso usarlo contro gli attacchi dizionario o brute force.
Le rainbow table stesse sono invecchiate nel corso degli anni. Con le recenti implementazioni di password cracker basati su CUDA/OpenCL e l’enorme quantità di parallelismo disponibile con le GPU moderne, si riesce a raggiungere una potenza di calcolo di miliardi di password al secondo. Si può letteralmente provare ogni combinazione di password inferiore ai 7 caratteri in meno di 2 secondi. E adesso si può anche affittare l’hardware che lo rende possibile per meno di 3 dollari l’ora.

Con l’enorme shift nell’economia degli attacchi crittografici non ha più senso per nessuno sprecare TB di spazio su disco nella speranza che la vittima non abbia usato il salt. E’ molto più facile semplicemente craccare la password. Persino un “buon” hashing schema come SHA256 con salt è completamente vulnerabile a questi attacchi economici. Quì dunque l’importanza di usare un algoritmo di hashing adattabile come bcrypt per salvare le password nel proprio DB.