In generale, non è necessario utilizzare più di un algoritmo di hashing.
Quello che devi fare è:
Usa sale: sale non è usato solo per rendere la più sicura , è usata per un attacco da tavolo arcobaleno. In questo modo, qualcuno avrà un lavoro più difficile nel tentativo di precalorizzare l'hash per le password memorizzate nel tuo sistema.
Usa più interazioni: invece di fare solo SHA (password + sale), fai SHA (SHA (SHA (SHA (SHA (... SHA (password + sale)))))). Oppure, per rappresentare in altro modo:
hash = sha(password + salt)
for i=1 , i=5000, i++ {
hash = sha(hash + salt);
}
E, infine, scegli una buona funzione di hashing. SHA, MD5, ecc. Non sono buoni perché sono troppo veloci . Dal momento che si desidera utilizzare l'hash per la protezione, è consigliabile utilizzare hash più lenti. Dai un'occhiata a Bcrypt , PBKDF2 o Scrypt , ad esempio.
modifica : dopo le osservazioni, proviamo a vedere alcuni punti (scusa, una lunga spiegazione per arrivare alla fine, perché potrebbe aiutare gli altri a cercare risposte simili):
Se il tuo sistema è sicuro, come se nessuno avesse mai accesso alla password memorizzata, non avresti bisogno dell'hash. La password sarebbe stata segreta, nessuno avrebbe capito.
Ma nessuno può assicurare che il database con le password venga rubato. Ruba il database, hai tutte le password. Ok, il tuo sistema e la tua azienda ne soffriranno tutte le conseguenze. Quindi, potremmo provare ad evitare questa perdita di password.
AVVISO che non siamo preoccupati per gli attacchi online in questo punto. Per un attacco online, la soluzione migliore è rallentare dopo password sbagliate, bloccare l'account dopo alcuni tentativi, ecc. E per quello non importa in che modo criptare, hash, memorizzare, ecc. La tua password. L'attacco online è una questione di rallentare gli input della password .
Quindi, torniamo al problema don't let them take my plain passwords
. La risposta è semplice: non memorizzarli come testo normale. Ok, capito.
Come evitarlo?
Encrypt the password (?). Ma, come sai, se lo cripti, puoi decrittografarlo di nuovo, se hai la chiave corretta. E finirai con il problema di "dove nascondere" la chiave. Hum, non va bene, dato che ti hanno dato un database, loro possono prendere la tua chiave. Ok, non usarlo.
Quindi, un altro approccio: trasformiamo la password in qualcos'altro che non può essere invertito e memorizzarlo. E per verificare se la password fornita è corretta, eseguiamo di nuovo la stessa procedura e controlliamo se i due valori tranformati corrispondono. Se corrispondono = è stata fornita la buona password.
Ok, finora tutto bene. Usiamo alcuni hash MD5 nella password. Ma ... se qualcuno ha il nostro valore hash memorizzato della password, può avere un sacco di potenza del computer per calcolare l'hash MD5 di ogni possibile password (forza bruta), in modo che possa trovare la password originale. O, peggio ancora, può memorizzare tutti gli MD5 da tutte le combinazioni di caratteri e trovare facilmente la password. Quindi, fai molte iterazioni, la cosa HASH (HASH (HASH ())), per renderla più difficile, perché ci vorrà più tempo.
Ma anche questo può essere aggirato, il tavolo arcobaleno è stato creato esattamente per accelerare questo tipo di protezione.
Quindi, usiamo un po 'di sale su di esso. In questo modo, ad ogni interazione, il sale viene nuovamente utilizzato. Un tentativo di attaccare le tue password dovrà generare la tabella arcobaleno considerando che il sale viene aggiunto ogni volta. E quando genera quel tavolo arcobaleno, poiché è stato generato con un solo sale, dovrà calcolare di nuovo con l'altro sale, quindi dovrà trascorrere un po 'di tempo per ogni password (= ogni sale). Salt non aggiungerà "più complessità" alla password, ma farà sì che l'attaccante perda tempo a generare la tavola dell'arcobaleno, se si usa un salt per ogni password, la tabella da un salt è inutile con un'altra password.
E usare più di un hash ci sarà d'aiuto? No. La persona che genera un attacco arcobaleno specifico sarà in grado di generarlo usando uno o più hash, comunque.
E l'utilizzo di più di un hash può portare a un problema: è sicuro quanto l'hash più debole che usi. Se qualcuno trova le collisioni in un algoritmo di hash, è quell'hash che verrà sfruttato, in qualsiasi punto del processo di iterazione, per infrangere la password. Quindi, non ottieni nulla usando più algoritmi di hash, è meglio scegliere solo un buon algo. e usarlo. E se mai senti che è stato rotto, pensa a come lo cambierai nella tua applicazione.
E perché usare bcrypt o qualcosa del genere (tu dici di usarlo): perché l'attaccante dovrà passare più tempo a generare le tabelle. Ecco perché l'utilizzo di MD5 + wait (3 secondi) non aiuta: l'attacco sarà offline, comunque, in modo che l'attaccante possa generare le tabelle senza (3 secondi di ritardo).