Perché i sali rendono “impossibili” gli attacchi dei dizionari?

Aggiornamento: Si prega di notare che non sto chiedendo che cos’è un sale, che cos’è un tavolo arcobaleno, che cos’è un attacco di dizionario o qual è lo scopo di un sale. Sto interrogando: se conosci gli utenti salt e hash, non è abbastanza facile calcolare la loro password?

Capisco il processo e lo implemento personalmente in alcuni dei miei progetti.

s = random salt storedPassword = sha1(password + s) 

Nel database che memorizzi:

 username | hashed_password | salt 

Ogni implementazione di salatura che ho visto aggiunge il sale alla fine della password o all’inizio:

 hashed_Password = sha1(s + password ) hashed_Password = sha1(password + s) 

Pertanto, un attacco di dizionario da parte di un hacker che vale il suo sale (ah ah) dovrebbe semplicemente eseguire ogni parola chiave contro i sali memorizzati nelle combinazioni comuni elencate sopra.

Sicuramente l’implementazione sopra descritta aggiunge semplicemente un altro passo per l’hacker, senza in realtà 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 è un algoritmo di fusione segreto che lega salt e password in un pattern 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 merletti loro per un attacco di dizionario per dimostrarsi fruttuoso. (Aggiornamento, come indicato nei commenti, è meglio presumere che l’hacker abbia accesso a tutte le tue informazioni, quindi probabilmente non è la cosa migliore).

Lasciatemi fare un esempio di come propongo a un hacker di 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 comune delle password:

  Common Password -------------- letmein 12345 ... 

Per ogni record utente, eseguire il loop delle password comuni e cancellarle:

 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 il mio punto di vista molto meglio.

Dato 10.000 password comuni e 10.000 record utente, avremmo bisogno di calcolare 100.000.000 di hash per scoprire quante più password utente ansible. Potrebbero essere necessarie alcune ore, ma non è davvero un problema.

Aggiornamento sulla teoria del crack

Assumeremo che siamo un webhost 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. (Nella situazione del mondo reale probabilmente sarà più lento, 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 il tasso di calcolo (variabile), diviso per 2 (supponendo che il tempo medio per scoprire la password richiederà in media il 50% delle permutazioni) per 10.000 gli utenti impiegherebbero 177 secondi per elaborare tutte le password degli utenti in cui la lunghezza è <= 4.

Aggiustiamolo un po ‘per realismo.

(((36 ^ 7) / 1000000000) / 2) * 10000 = 2 giorni

Assumendo la non 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 le circostanze generali e non ideali.

È importante riconoscere che si tratta di un attacco di forza bruta lineare, tutti i calcoli sono indipendenti l’uno dall’altro, quindi è un compito perfetto per la risoluzione di più sistemi. (IE facile da configurare 2 computer che eseguono attacchi da estremità diverse che sarebbero la metà del tempo di esecuzione).

Dato il caso di hashing ricorsivo di una password 1.000 volte per rendere questa attività più dispendiosa dal punto di vista computazionale:

(((36 ^ 7) / 1 000 000 000) / 2) * 1000 secondi = 10,8839117 ore

Ciò rappresenta una lunghezza massima di 7 caratteri alfanumerici, a un’esecuzione a meno di metà velocità rispetto alla cifra indicata per un utente .

L’hashing ricorsivo 1.000 volte blocca efficacemente un attacco generale, ma gli attacchi mirati ai dati dell’utente sono ancora vulnerabili.