it-swarm-eu.dev

Salare un hash è davvero sicuro come implica la conoscenza comune?

(Ho cercato su questo argomento, ma non ho trovato nessuna domanda/risposta completa a cui si è rivolto, o anche buone parti di domande che potrebbero essere pertinenti.)

Sto implementando una funzione salt per le password degli utenti sulla mia pagina web e mi chiedo alcune cose.

Un salt è un'estensione aggiunta a una password e quindi l'hash, il che significa che la password è memorizzata nel database come hash(password+salt). Ma dove si conserva il sale? Un sale è semplicemente quello di rendere le tabelle Rainbow "inutili", giusto?

Un attaccante non potrebbe semplicemente costruire un tavolo Rainbow, quindi convertire tutti gli hash e rimuovere il sale? Dopotutto, il sale è memorizzato da qualche parte nel database. Pertanto, se si possono trovare le password con hash, si dovrebbe essere in grado di trovare i sali corrispondenti. Mi sembra che solo un sale allunghi le password, costringendo il tavolo Rainbow a durare più a lungo.

Quindi, come si fa a massimizzare l'efficacia di un sale? Non vedo davvero più motivi di sicurezza per questo, oltre a rendere le password più lunghe dinamicamente, ma di nuovo si potrebbero invece convertirle in bit in una stringa.

I miei presupposti su come un sale funziona correttamente? In caso contrario, come devo memorizzarlo e le password salate correttamente?

39

Hai fondamentalmente ragione che sta solo allungando la password ma ci sono alcune cose aggiuntive che aggiunge. Inoltre la password media non è così lunga o sicura e raramente aggiungere lunghezza "gratis" è male. Il salt fa in modo che un utente malintenzionato non possa hash "password" una volta e quindi cercare ogni utente che abbia una password di "password".

Dovrebbero invece generare hash di "password03j9834nfp-3028n408" e "passwordn0438wnvas89v5sne" e ... Ciò aumenta notevolmente la protezione dell'identificazione di password non sicure e ha ancora un vantaggio positivo sull'aumentare la difficoltà di trovare password sicure.

Il punto in cui si capisce la tua comprensione è quando dici "Un attaccante non potrebbe semplicemente costruire un tavolo Rainbow, quindi convertire tutti gli hash e rimuovere il sale?". Ci sono alcuni problemi qui.

Il primo è quello delle collisioni. Una tabella Rainbow non è garantita per produrre l'input originale, è solo interessata a produrre un input che ha prodotto l'output desiderato. Dato che il sale verrà aggiunto a qualunque cosa l'utente inserisca, l'attaccante deve trovare l'input esatto che è stato usato per l'hash.

Dato che deve essere trovato l'input esatto, il vantaggio di una tabella Rainbow per sfruttare le collisioni è perso. Inoltre, la dimensione richiesta per forzare la forza di tutti i possibili sali sarebbe troppo grande per essere trattenuta da qualsiasi attaccante.

Inoltre, non puoi semplicemente rimuovere il sale da un hash senza capire quale fosse l'input originale. Dovresti cercare un valore che termina nel sale che corrisponde all'hash dato. Ciò richiede quindi che venga prodotta una tabella Rainbow separata per ogni valore di salt nel DB e ciò vanifica la capacità di pre-calcolo poiché non è possibile creare una tabella Rainbow per ogni possibile salt.

26
AJ Henderson

Hai un'idea sbagliata fondamentale di come funzionano i tavoli Rainbow.

Una tabella Rainbow o una tabella hash viene creata da un utente malintenzionato precedente a un attacco. Supponiamo di creare una tabella hash contenente tutti gli hash delle stringhe inferiori a 7 caratteri per MD5. Se comprometto il tuo database e ottengo un elenco di hash, tutto quello che devo fare è cercare l'hash sul tavolo per ottenere la tua password.

Con un salt, non puoi generare una tabella Rainbow per un algoritmo specifico precedente a un attacco. Un salt non è pensato per essere segreto, lo memorizzi insieme all'hash nel tuo database.

x = hash(salt+password) Lo memorizzerai nel tuo database nel formato di salt+x Ciò renderà inutili le tabelle Rainbow e le tabelle hash.

Come al solito, non usare il tuo, usa bcrypt, scrypt o pbkdf2 Che si prende cura di tutti i dettagli inclusa la salatura per te. Vedi Come eseguire l'hashing sicuro delle password?

53
user10211

A Rainbow table è un'ottimizzazione per invertire gli hash con la forza bruta. Funziona con un compromesso: fai un sacco di precomputazione per costruire un'enorme struttura di dati e puoi quindi rompere rapidamente molti hash.

Un tavolo Rainbow aiuta solo gli hash crack nello spazio di ricerca che copre. Concretamente, i tavoli Rainbow sono costruiti per caratteri semplici composti da caratteri stampabili e [fino a una certa lunghezza. Il principio base dell'aggiunta di un salt è che il testo in chiaro che è hash contiene sia la password che il salt; con il sale aggiunto, lo spazio di ricerca diventa troppo grande per costruire una tabella Rainbow .

Pertanto, aggiungendo un salt alla password, non c'è modo di ammortizzare il costo di un attacco di forza bruta su molte crepe. L'attaccante deve fare tutto il lavoro per ogni hash, iniziando solo quando conosce il sale.

Dato un hash e un sale, non c'è modo di "rimuovere il sale". Questa è una proprietà di base di una funzione hash: anche se sai che sono correlate due stringhe (ad esempio sai che la password è una sottostringa di password + salt), non ti aiuta a trovare l'hash (password) conoscendo l'hash (password + sale). Non è necessario nascondere il sale all'attaccante : deve essere unico (e non derivato dalla password ) ma non deve essere più segreto del hash. (Puoi aggiungere un ulteriore sale segreto, che si chiama pepe , ma è utile solo in una serie ristretta di circostanze.)

Salare l'hash è solo metà della battaglia. Un'altra parte delle password di hashing in sicurezza è che la funzione di hash deve essere lenta, perché danneggia il cracker molto più del verificatore. Non tirare il tuo , usa un metodo che è stato controllato dagli esperti. Usa bcrypt o PBKDF2 o scrypt . L'implementazione dell'archiviazione delle password non dovrebbe comportare la crittografia, chiamare una funzione di libreria.

Per tutto ciò che volevi sapere sulle password di hashing, tutto ciò che non volevi sapere sulle password di hashing e tutto ciò che non sapevi nemmeno di sapere sulle password di hashing, leggi Come eseguire l'hashing sicuro delle password? =

Un unico sale risolve un problema: ogni account non può essere attaccato contemporaneamente in un gigantesco tentativo di forza bruta.

Supponiamo che tu abbia provato a costruire una tabella Rainbow con tutte le password stampabili ASCII che fossero lunghe 8 caratteri1. Sono 968 ~ 7,2 milioni di miliardi (7,2 x 1015) possibilità. Se hai una GPU che genera password a un miliardo al secondo, ci vorrà circa un mese circa per decifrare (e a 200 W a $ 0,10 per kWhr è in media circa $ 200; ~ $ 400 nel peggiore dei casi per la bolletta elettrica).

Quindi scopri gli hash di ogni account su linkedin da una sorta di iniezione SQL o trova un disco rigido con un vecchio backup. Hai hash di un milione di utenti. Ora, se sono hash non salati, puoi rompere la stragrande maggioranza di questi hash in due mesi con una GPU per circa $ 400 di elettricità. Se sono tutti salati in modo univoco e vuoi romperne tutti i milioni, ora ci vorranno $ 400 milioni di dollari di elettricità poiché ogni singolo sale deve avere il suo attacco indipendente. Ora, prima di dirlo, costruirò un tavolo Rainbow più grande che include i sali, rendendomi conto che almeno un sale tipico ha 5 caratteri esadecimali (16 ** 5), il che significa che ci vorrà un milione di volte in più per creare il tuo Rainbow tabella (ad esempio, dovrai spendere $ 400 milioni per l'elettricità per generarlo).

Ora aggiungi il rafforzamento chiave dove invece di eseguire l'hash una volta, ripeterai il processo N volte (ad esempio, una funzione hash iterata per tre volte sarebbe: hash(salt+hash(salt+hash(salt+pw)))). Ora invece di essere in grado di rompere un miliardo di hash al secondo, possono rompere un miliardo/N di hash al secondo, quindi tutti gli attacchi saranno N volte più costosi. (Una N tipica è 5000; quindi per rompere un singolo hash occorrerebbero circa 2 milioni di dollari in elettricità; il problema con una N super grande è che le sue risorse di calcolo più elevate sui server per la verifica dei tentativi di password).

1 - Questo non è il modo più efficace per decifrare le password. Gli elenchi di dizionario di milioni di password utilizzate in precedenza sono molto più efficaci, poiché molte password sono piuttosto deboli. Non consiglio alle persone di generare password (in genere un'entropia molto bassa) o di riutilizzare le password. Utilizzare un servizio come keepassx che consente di creare password casuali per ciascun sito e archiviarle in un file crittografato. Rinforzo chiave + sale unico significa che è impossibile provare a rompere tutti gli hash tranne i più semplici.

9
dr jimbob

Le tabelle Rainbow sono tabelle hash pre-calcolate che vengono utilizzate per decifrare le password in un tempo relativamente più veloce perché la ricerca di una tabella è molto più rapida rispetto al calcolo di un hash.

se si possono trovare le password con hash, si dovrebbe essere in grado di trovare i sali corrispondenti

Il salt noto all'attaccante non creerà un grosso problema se l'attaccante sta cercando di decifrare una password singola . Il salt renderà difficile e dispendioso in termini di tempo decifrare un elenco di password perché per ogni password il salt è diverso.

Ma dove si conserva il sale? Un sale è semplicemente quello di rendere le tabelle Rainbow "inutili", giusto?

Salt è memorizzato solo nel DB e per ogni password si ha un salt casuale diverso. Sì il salt rende molto difficile usare una tabella Rainbow. Le tabelle Rainbow sono generalmente create utilizzando password comuni utilizzate. L'aggiunta di un sale casuale rende molto difficile essere crackati da un tavolo Rainbow.

Un attaccante non potrebbe semplicemente costruire un tavolo Rainbow, quindi convertire tutti gli hash e rimuovere il sale?

Forse intendi dire costruire un tavolo arcobaleno con sali noti (prima di eseguire il vero attacco) perché non puoi semplicemente rimuovere un sale dall'hash. Ricalcolo della tabella non è raccomandato perché se si tiene conto di tutti i sali noti la dimensione della tabella sarà troppo grande. Ricordare lo spazio/tempo. Se crei le tabelle per un sale alla volta stai sprecando troppa energia. Lo scopo principale della creazione di una tabella Rainbow è quello di decifrare un elenco di password e non una singola password.

Un'altra aggiunta di valore molto importante che fornisce la salatura è non ci sono due utenti che finiranno con un identico hash di password perché i sali saranno diversi. Immagina che un utente malintenzionato sia in grado di decifrare una delle password e se i sali non vengono utilizzati l'attaccante deve semplicemente cercare per scoprire quali altri utenti utilizzano la stessa password.

2
Shurmajee

Innanzitutto, perché stai implementando un codice crittografico di basso livello per una pagina web? Penseresti che questo sia un problema risolto: usi un framework che usa le librerie.

In secondo luogo, l'hash protegge le password nel caso in cui gli hash fuoriescano. Il tuo sito non fornisce accesso al database delle password, quindi idealmente questa situazione non dovrebbe nemmeno presentarsi. I sali aiutano a difendere l'intero database delle password in quell'evento.

Se l'attaccante si concentra su una singola password di quel database, allora non fa molta differenza. Rende solo il lavoro più difficile, nel senso che l'attaccante non può semplicemente recuperare la password da una tabella Rainbow cercando l'hash. La forzatura bruta di una password con un sale è solo leggermente rallentata perché viene eseguito l'hashing di qualche byte in più che costa qualche altro ciclo macchina nei round di hashing.

C'era una volta, i sistemi Unix che offrivano l'accesso pubblico (come i sistemi del campus per gli studenti) avevano le loro password incrinate a destra e sinistra. Vi erano vari motivi per cui questo era facile, ma il problema principale era semplice: le informazioni di hash della password sensibili erano mantenute nello stesso file degli altri campi di informazioni su un utente e quel file, /etc/passwd era leggibile in tutto il mondo. La correzione consiste nel mettere le informazioni sensibili in un file separato, /etc/shadow. Presto: che termina la violazione della password da parte dei kiddie degli script che dispongono di account legittimi senza privilegi sul sistema.

Allo stesso modo, nessuno sarà brutale forzando le tue password a meno che non le lasci fuoriuscire. Se fuoriescono e qualcuno cerca la password di un determinato utente, c'è poco che si può fare per fermarli.

Gli utenti che usano le stesse password su sistemi diversi e non la cambiano per anni saranno sempre vulnerabili. Puoi salarlo, peparlo e aggiungere ketchup; non farà differenza.

I sali scoraggiano qualcuno che vuole decifrare il database delle password nel suo insieme e raccogliere quante più password possibili. I sali indicano che ogni password deve essere forzata individualmente anziché recuperata da tabelle precalcolate. Se un salt ha N bit, allora, almeno idealmente, il database della tabella Rainbow dell'attaccante deve essere 2 ^ N volte più grande. Un salt a 32 bit significa che è necessario un database di tabelle Rainbow quattro miliardi di volte più grande per cercare solo le password.

Se il tuo sito ha solo 20 utenti, ovviamente ci sono solo 20 diversi sali. Quindi, ciò che un utente malintenzionato farà è prendere il dizionario delle password e hash ogni voce in 20 modi diversi con quei sali.

Quindi i sali non solo proteggono il tuo database dalla ricerca della tabella Rainbow, ma lo proteggono anche dal cracking della forza bruta di circa un fattore di N, dove N è il numero di utenti. Per forzare la password N, l'attaccante deve eseguire N volte il lavoro come forza bruta forzandone una. (Supponendo che il sale sia abbastanza largo: almeno grande quanto il logaritmo di base 2 di N. Se un sale è solo, diciamo, largo 12 bit, allora ci possono essere solo 4096 sali diversi, non importa quanti utenti ci siano.)

Senza sali, questo non è vero. Forzare brutalmente un numero qualsiasi di password allo stesso tempo è facile come forzare brutalmente una, quindi più utenti ci sono, maggiore è il profitto per sforzo.

1
Kaz

Ci sono un paio di fattori coinvolti nella salatura e ti manca (almeno) uno di quelli.

  • Rendono inutili i tavoli Rainbow. Se qualcuno cerca nel tuo database delle password e vede che una password è "5f4dcc3b5aa765d61d8327deb882cf99", non ha nemmeno bisogno di costruire una "tabella Rainbow", può semplicemente google per quel valore e google dirà loro che è l'hash md5 di " parola d'ordine". Se le password sono sottoposte a hash prima di essere inserite nel tuo db, il meccanismo di ricerca "Rainbow table" sarà inutile. Non è necessario conservare il sale nel db per rendere inutili le tabelle Rainbow. Il tuo sale può sempre essere "xxxx" o qualsiasi altra stringa arbitraria. Se si utilizza Google per 6a316e1fdac8a61d9c7a2ed1cba4a804 (l'hash md5 di "xxxxpassword"), non si ottengono risultati.

  • Se fatto correttamente, in genere significa che un intruso ha bisogno di entrambi il tuo database e il tuo codice per decifrare le tue password. Potresti aver eseguito l'hashing della tua password come "xxxx" + password o pw.substring (0,2) + "xxxx" + pw.substring (2). L'attaccante non sa come hai salato le tue password a meno che non abbia rubato anche il tuo codice. Il tuo server web spesso non funziona nella stessa casella del tuo database e con i linguaggi di programmazione compilati il ​​tuo codice potrebbe non essere nemmeno disponibile sul tuo server web. Indipendentemente da quali sali memorizzi nel tuo db, consiglierei anche di avere un lungo, arbitrario, sale fisso memorizzato all'esterno del db che viene ulteriormente concatenato alla password prima dell'hash.

  • Sali unici rendono il cracking più costoso. Come ha sottolineato qualcun altro, se si esegue il hash di ogni parola del dizionario con un salt statico ("xxxx"), è possibile scansionare l'intero database delle password per "6a316e1fdac8a61d9c7a2ed1cba4a804" alla ricerca di chiunque abbia la password "password". Se ogni riga utilizza un sale diverso, devi eseguire N hash solo per scoprire se uno degli N utenti ha la password "password".

  • Sul secondo punto, fai attenzione a usare solo un singolo sale fisso fisso senza nessun altro. Un cracker potrebbe provare a eseguire l'hashing di stringhe arbitrarie + "password" fino a quando non trova qualcuno che ha la password "password", e quindi sostanzialmente si spaccherebbe il sale. In qualsiasi grande database di password è inevitabile che ci sia almeno un utente la cui password è una password banale come "password".

0
Brian