Aggiornamento: Nota che non sto chiedendo cos'è un sale, cos'è una tavola arcobaleno, cos'è un attacco del dizionario o qual è lo scopo di un sale. Sto chiedendo: se conosci gli utenti salt e hash, non è abbastanza facile calcolare la loro password?
Comprendo il processo e lo implemento io stesso in alcuni dei miei progetti.
s = random salt
storedPassword = sha1(password + s)
Nel database memorizzi:
username | hashed_password | salt
Ogni implementazione del salting che ho visto aggiunge il salt alla fine della password o all'inizio:
hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)
Pertanto, un attacco al dizionario da parte di un hacker che vale il suo sale (ah ah) eseguirà semplicemente ogni parola chiave contro i sali immagazzinati nelle combinazioni comuni elencate sopra.
Sicuramente l'implementazione sopra descritta aggiunge semplicemente un altro passaggio per l'hacker, senza effettivamente risolvere il problema sottostante? Quali alternative ci sono per aggirare questo problema o sto fraintendendo il problema?
L'unica cosa che posso pensare di fare è avere un algoritmo di miscelazione segreto che lega insieme il salt e la password in uno schema casuale, o aggiunge altri campi utente al processo di hashing, il che significa che l'hacker dovrebbe avere accesso al database E al codice per allacciare perché un attacco al dizionario si dimostrasse fruttuoso. (Aggiorna, come sottolineato nei commenti, è meglio presumere che l'hacker abbia accesso a tutte le tue informazioni, quindi questo probabilmente non è il migliore).
Vorrei fare un esempio di come propongo che un hacker possa hackerare un database utente con un elenco di password e hash:
Dati dal nostro database compromesso:
RawPassword (not stored) | Hashed | Salt
--------------------------------------------------------
letmein WEFLS... WEFOJFOFO...
Dizionario delle password comuni:
Common Password
--------------
letmein
12345
...
Per ogni record utente, loop le password comuni e hash:
for each user in hacked_DB
salt = users_salt
hashed_pw = users_hashed_password
for each common_password
testhash = sha1(common_password + salt)
if testhash = hashed_pw then
//Match! Users password = common_password
//Lets visit the webpage and login now.
end if
next
next
Spero che questo illustri molto meglio il mio punto.
Date 10.000 password comuni e 10.000 record utente, dovremmo calcolare 100.000.000 hash per scoprire quante più password utente possibile. Potrebbero essere necessarie alcune ore, ma non è davvero un problema.
Aggiornamento sulla teoria del cracking
Daremo per scontato di essere un host web corrotto, che ha accesso a un database di hash e sali SHA1, insieme al tuo algoritmo per fonderli. Il database ha 10.000 record utente.
Questo sito afferma di essere in grado di calcolare 2.300.000.000 di hash SHA1 al secondo utilizzando la GPU. (Nel mondo reale la situazione probabilmente sarà più lenta, ma per ora useremo quella cifra citata).
(((95 ^ 4) / 2300000000) / 2) * 10000 = 177 secondi
Dato un intervallo completo di 95 caratteri ASCII stampabili, con una lunghezza massima di 4 caratteri, diviso per la velocità di calcolo (variabile), diviso 2 (assumendo che il tempo medio per scoprire la password richiederà in media il 50% di permutazioni) per 10.000 gli utenti impiegherebbero 177 secondi per elaborare tutte le password degli utenti la cui lunghezza è <= 4.
Regoliamolo un po 'per realismo.
(((36 ^ 7) / 1000000000) / 2) * 10000 = 2 giorni
Supponendo che non sia fatta distinzione tra maiuscole e minuscole, con una lunghezza della password <= 7, solo caratteri alfanumerici, ci vorrebbero 4 giorni per risolvere 10.000 record utente e ho dimezzato la velocità dell'algoritmo per riflettere circostanze generali e non ideali.
È importante riconoscere che questo è un attacco di forza bruta lineare, tutti i calcoli sono indipendenti l'uno dall'altro, quindi è un compito perfetto da risolvere per più sistemi. (IE è facile da configurare 2 computer che eseguono attacchi da estremità diverse che richiederebbero la metà del tempo di esecuzione).
Dato il caso di hashing ricorsivamente di una password 1.000 volte per rendere questa attività più costosa dal punto di vista computazionale:
(((36 ^ 7) / 1.000.000.000) / 2) * 1000 secondi = 10,8839117 ore
Rappresenta una lunghezza massima di 7 caratteri alfanumerici, a una velocità di esecuzione inferiore alla metà rispetto alla cifra indicata per un utente .
L'hashing ricorsivo 1.000 volte blocca efficacemente un attacco globale, ma gli attacchi mirati ai dati degli utenti sono ancora vulnerabili.