È più sicuro eseguire l'hashing di una password più volte?


43

Ho letto alcune volte che quando si memorizzano le password, è buona norma "raddoppiare" le stringhe (ad es. Con md5 e poi sha1, entrambe con i sali, ovviamente).

Immagino che la prima domanda sia: "è davvero corretto?" In caso contrario, per favore, respinge il resto di questa domanda :)

Il motivo per cui lo chiedo è che, a prima vista, direi che questo ha senso. Tuttavia, quando ci penso, ogni volta che un hash viene rimodellato (possibilmente con qualcosa aggiunto ad esso) tutto ciò che posso vedere è che c'è una riduzione del limite superiore della "unicità" finale ... quel limite è collegato a l'input iniziale.

In altre parole: abbiamo un numero x di stringhe che, quando sono sottoposte a hash, vengono ridotte a y possibili stringhe. Vale a dire, ci sono collisioni nel primo set. Ora, dal secondo al terzo set, non è possibile che si verifichi la stessa cosa (es. Collisioni nel set di tutte le possibili stringhe 'y' che danno lo stesso hash nel terzo set)?

Nella mia testa, tutto quello che vedo è un 'imbuto' per ogni chiamata di funzione hash, 'incanalando' un insieme infinito di possibilità in un set finito e così via, ma ovviamente ogni chiamata sta lavorando sul set finito prima di esso, dandoci un impostare non più grande dell'input.

Forse un esempio spiegherà le mie divagazioni? Prendi 'hash_function_a' che darà a 'a' e 'b' l'hash '1', e darà 'c' e 'd' l'hash '2'. Usando questa funzione per memorizzare le password, anche se la password è 'a', potrei usare la password 'b'.

Prendi 'hash_function_b' che darà a '1' e '2' l'hash '3'. Se dovessi usare esso come un 'hash secondaria' dopo 'hash_function_a' quindi anche se la password è 'un' potrei usare 'b', 'c' e 'd'.

Inoltre, ho capito che dovrebbero essere usati i sali, ma non cambiano il fatto che ogni volta mappiamo gli input "x" su output "inferiori a x". Non penso

Qualcuno può spiegarmi cosa mi manca qui?

Grazie!

EDIT: per quello che vale, non lo faccio da solo, uso bcrypt. E non sono davvero preoccupato se sia utile o meno per "utilizzare i cicli" per un "hacker". Mi chiedo sinceramente se il processo riduca o meno la "sicurezza" dal punto di vista della collisione dell'hash.


2
@ S.Lott: Non vedo davvero come questo risponda alla vera domanda, però ... tutto ciò che dice è "non farlo da solo, usa questa cosa" o "è bello prenderti del tempo!". .. nessuna delle due risposte "è in realtà più sicura". Ancora una volta, a meno che non mi manchi qualcosa.
Narciso,

@MetalMikester: Sì, è stato l'articolo di ieri: thedailywtf.com/Articles/Bulletproof-Encryption.aspx
FrustratedWithFormsDesigner

Questo non è in argomento per la sicurezza IT, ma sembra una buona corrispondenza per la crittografia. In effetti, sembra estremamente simile a questa domanda lì .

Conosco un'azienda che voleva utilizzare non salati MD5(password). Abbiamo detto che non è sicuro, quindi hanno suggerito di usare MD5(MD5(password))invece ...
Configuratore

La risposta accettata non è la risposta corretta!
markus

Risposte:


27

Questo è più adatto su security.stackexchange ma ...

Il problema con

hash1(hash2(hash3(...hashn(pass+salt)+salt)+salt)...)+salt)

è che questo è solo forte della funzione di hash più debole della catena. Ad esempio se hashn (l'hash più interno) provoca una collisione, l'intera catena di hash provoca una collisione ( indipendentemente da quali altri hash si trovano nella catena ).

Una catena più forte sarebbe

hash1(hash2(hash3(...hashn(pass + salt) + pass + salt) + pass + salt)...) + pass + salt)

Qui evitiamo il problema delle prime collisioni e generiamo essenzialmente un sale che dipende dalla password per l'hash finale.

E se un passaggio nella catena si scontra, non importa perché nel passaggio successivo la password viene riutilizzata e dovrebbe dare un risultato diverso per password diverse.


Quindi in questo momento vedo che l'aggiunta di "password + salt" come sale al prossimo round di hashing potrebbe aumentare la quantità di "roba" che potrebbe andare nell'imbuto, ora devo solo capire da "quanto". Grazie.
Narciso,

In realtà penso di averlo capito subito: forzando la password in ogni livello dell'hash, sta effettivamente riducendo il numero di possibili collisioni richiedendo essenzialmente "la password di collisione" e la vera password per avere hash corrispondenti su ogni "chiamata" , destra? Sto pensando che mi mancava la parte 'inserisci la password in ogni livello'! Grazie ancora.
Narciso

@Narcissus no prob e che ha anche il vantaggio di consentire hash interni più deboli (purché gli hash esterni / finali siano forti) poiché gli hash interni generano solo il sale per il passaggio successivo
maniaco del cricchetto

hum, penso che il problema sia un po 'più grande (e più profondo) di quello. Con gli attacchi arcobaleno, puoi semplicemente generare tabelle considerando tutti i tuoi hash e il problema rimane.
woliveirajr,

4
@Narciso: in una risposta molto breve: Sì, non è più sicuro. Sì, probabilmente è ancora meno sicuro.
Woliveirajr,

54

L'uso di diversi algoritmi di hashing è una cattiva idea: ridurrà l'entropia anziché aumentarla.

Tuttavia, supponendo che abbiate un algoritmo di hash crittograficamente forte e un buon sale, l'applicazione della stessa funzione di hash più volte rende il processo di hashing più costoso dal punto di vista computazionale. Il vantaggio di questo è che quando altri mezzi per decifrare l'hash della password falliscono (ipotesi, attacchi con dizionario, tabelle arcobaleno, ecc.) E l'attaccante viene costretto a tecniche di forza bruta, impiega più tempo a provare ogni password, semplicemente perché devono applicare la stessa funzione hash più spesso. Quindi, se un ciclo di hashing richiederebbe un mese di forzatura bruta, applicarlo dodici volte aumenterebbe il tempo stimato a un anno.

Recenti algoritmi di hashing come bcrypt si basano su questa idea; contengono un parametro per controllare la complessità computazionale dell'hash, in modo da poterlo ridimensionare con il progredire della velocità dell'hardware: quando l'hardware diventa più veloce di un fattore due, aumenta la complessità per compensare, quindi il tempo necessario per forzare la forza gli hash rimangono all'incirca costanti.


2
Questa è la risposta corretta!
markus

@markus: come per la discussione che ho letto, questo è corretto solo per l'aggiunta "e un buon sale" a cui si rivolge la risposta accettata, non è vero? Perché questa è corretta e la risposta accettata no?
Narciso

È la risposta corretta perché l'unico motivo per applicare la stessa funzione di hashing più volte (con parametri) è che è possibile utilizzare questa iterazione per adattarsi a un hardware più veloce. In caso contrario, non è possibile trarre vantaggio dall'hashing più volte.
markus,

@Narciso La chiave qui è l'entropia. C'è una differenza tra l'hashing molte volte utilizzando lo stesso metodo rispetto all'hashing molte volte utilizzando metodi diversi.
sakisk,

3

Non provare a scrivere il tuo schema di hashing della password a meno che tu non sia disposto a seguire un corso di crittografia e / o ingegneria della sicurezza.

È necessario utilizzare un'implementazione consolidata dell'hash delle password che a sua volta dovrebbe utilizzare una funzione di derivazione delle chiavi ( KDF ) come PBKDF2, bcrypt, scrypt o Argon2 più recente.

I buoni KDF includono un fattore di lavoro, di solito un numero di iterazioni, al fine di aumentare il costo degli attacchi offline. Si potrebbe dire che questi KDF hanno l'hash della password più volte, usando ogni volta lo stesso algoritmo. Non ha senso utilizzare l'algoritmo di digest di più messaggi, come sottolineato da altri.


1
il link https://crackstation.net/hashing-security.htm è bloccato dal firewall
moscerino

1
@gnat Per qualche motivo, avevo perso il tuo commento sull'URL bloccato. L'ho sostituito con un link a Wikipedia.
Erwan Legrand,

2

In generale, non è necessario utilizzare più di un algoritmo di hashing.

Quello che devi fare è:

Usa salt: salt non è usato solo per rendere la tua password più sicura , è usato per sottrarre attacchi da tavolo arcobaleno. In questo modo, qualcuno avrà un lavoro più duro cercando di pre-calcolare l'hash per le password che memorizzi nel tuo sistema.

Usa interazioni multiple: invece di fare solo SHA (password + salt), esegui SHA (SHA (SHA (SHA (SHA (SHA (password + salt)))))). 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 vanno bene perché sono troppo veloci . Dal momento che si desidera utilizzare l'hash per la protezione, è meglio utilizzare hash più lenti. Dai un'occhiata a Bcrypt , PBKDF2 o Scrypt , per esempio.

modifica : dopo le osservazioni, proviamo a vedere alcuni punti (scusate, lunga spiegazione per arrivare alla fine, perché potrebbe aiutare gli altri a cercare risposte simili):

Se il tuo sistema è sicuro, come nessuno potrà mai accedere alla password memorizzata, non avrai bisogno di hash. La password sarebbe segreta, nessuno l'avrebbe ottenuta.

Ma nessuno può assicurare che il database con le password verrà rubato. Ruba il database, ottieni tutte le password. Ok, il tuo sistema e la tua azienda ne soffriranno tutte le conseguenze. Quindi, potremmo provare a evitare questa perdita di password.

AVVISO che a questo punto non siamo preoccupati per gli attacchi online. Per un attacco online, la soluzione migliore è rallentare dopo password errate, bloccare l'account dopo alcuni tentativi, ecc. E per questo non importa in che modo crittografare, hash, archiviare, ecc., La password. L'attacco online è una questione di rallentamento degli input della password .

Quindi, tornando al don't let them take my plain passwordsproblema. La risposta è semplice: non archiviarli come testo normale. Ok capito.

Come evitarlo?

Crittografa la password (?). Ma, come sapete, se lo crittografate, è possibile decrittografarlo nuovamente, se si dispone della chiave corretta. E finirai con il problema di "dove nascondere" la chiave. Hum, non va bene, dato che ti hanno dato il database, possono ottenere la tua chiave. Ok, non usiamolo.

Quindi, un altro approccio: trasformiamo la password in qualcos'altro che non può essere invertito e salviamola. E per verificare se la password fornita è corretta, eseguiamo nuovamente lo stesso processo e controlliamo se i due valori trasformati corrispondono. Se corrispondono = è stata fornita la password corretta.

Ok, finora tutto bene. Usiamo un po 'di hash MD5 nella password. Ma ... se qualcuno ha il nostro valore hash di password memorizzato, può avere molta 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 tutto l'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 evitato, 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 riutilizzato. Uno che prova ad attaccare le tue password dovrà generare la tabella arcobaleno considerando che il sale viene aggiunto ogni volta. E quando genera quella tabella arcobaleno, poiché è stata generata con un solo sale, dovrà calcolare nuovamente con l'altro sale, quindi dovrà dedicare un po 'di tempo per ogni password (= ogni sale). Salt non aggiungerà "più complessità" alla password, farà perdere tempo all'attaccante generando la tabella arcobaleno, se usi un salt per ogni password, la tabella da un salt è inutile per un'altra password.

E l'utilizzo di più di un hash ti ha aiutato qui? No. La persona che genera un attacco arcobaleno specifico sarà in grado di generarlo utilizzando uno o più hash, comunque.

E usare più di un hash può portare a un problema: è sicuro come l'hash più debole che usi. Se qualcuno trova delle collisioni in un algoritmo di hash, è quell'hash che verrà sfruttato, in qualsiasi momento del processo di iterazione, per violare la password. Quindi, non ottieni nulla usando più algoritmi di hash, è meglio scegliere solo un buon algoritmo. e usalo. E se mai sapessi che è stato rotto, pensa a come lo cambierai nella tua applicazione.

E perché usare bcrypt o qualcosa del genere (dici di usarlo): perché l'attaccante dovrà impiegare più tempo a generare le tabelle. Ecco perché l'uso di MD5 + wait (3 secondi) non aiuta: l'attacco sarà offline, comunque, così l'attaccante può generare le tabelle senza il (ritardo di 3 secondi).


2
Oops! Mi dispiace, il mio commento (sul deliberatamente rallentare l'hash tramite il parametro timeout) non doveva essere preso sul serio ... Penso di aver letto troppo Dilbert ultimamente.
FrustratedWithFormsDesigner,

2
sha (sha (sha (...))) non è più sicuro di sha. Se l'entropia della funzione sha non è massima, questo è in realtà meno sicuro.
deadalnix,

1
@deadalnix: è importante ricordare che non semplifica il recupero della password originale, ma facilita la generazione di una password in collisione, che è tutto ciò che è necessario.
Bryan Boettcher,

1
@deadalnix, ho letto quel commento con la voce di Dale Gribble .
jiggy,

1
@deadalnix: l'obiettivo di sha (sha (sha ())) non è, e non lo è mai stato, aggiungere altra entropia. L'entropia viene fatta dall'utente iniziale scegliendo la sua password, tutto il resto (hash, salt, ecc.) Serve solo a rallentare un attacco a forza bruta. Se qualcuno è in grado di ottenere il tuo database contenente le password, probabilmente otterrà anche il codice utilizzato per eseguire l'hashing della password, quindi è noto anche qualsiasi sale hard-coded
woliveirajr

-1

La mia comprensione è che l'uso di più algoritmi di hashing è per sconfiggere le tabelle arcobaleno . Anche usare un buon sale funziona, ma immagino sia un secondo livello di protezione.


4
Bene, questo non cambia molto. La fucntion «hash multiplo» può essere vista come una sola e trattata come tale.
deadalnix,

2
L'uso di più tecniche di hashing o iterazioni non fa nulla per sconfiggere le tabelle arcobaleno. Se un utente malintenzionato dispone del database e utilizza il metodo utilizzato per generare gli hash, l'utente malintenzionato può quindi generare una tabella arcobaleno per attaccare tutte le password nel database. I SALI impediscono gli attacchi da tavolo arcobaleno poiché impediscono all'attaccante di generare un singolo dizionario di ricerca per attaccare, diciamo, tutte le password di 8 caratteri o meno.
Erik,

-1

Questo non è più sicuro. Tuttavia, hai un protocollo di identificazione basato sull'hash più volte con la stessa funzione.

Questo va così. Il valore memorizzato è hash ^ n (passa) nel computer A. A chiede a B di autenticare e dà a B il numero intero n. B esegue l'hash di calcolo ^ (n-1) (passa) e lo rimanda ad A.

Un controllo che hash (hash ^ (n-1) (pass)) == hash ^ n (pass). Se è vero, allora l'autenticazione è fatta. Ma poi, un negozio hash ^ (n-1) (pass) e la prossima autenticazione, darà B n-1 invece di n.

Ciò garantisce che la password non venga mai scambiata in modo chiaro, che A non sappia mai quale sia la password e che l'autenticazione sia protetta dalla riproduzione. Tuttavia, questo ha lo svantaggio di richiedere una password con una durata limitata. Quando n raggiunge il valore 2, una nuova password deve essere scelta dopo l'autenticazione.

Un altro uso dell'hash multiplo è lo strumento HMAC, per garantire l'autenticazione e l'integrità di una richiesta. Per ulteriori informazioni su HMAC, consultare http://en.wikipedia.org/wiki/HMAC .

La maggior parte dell'utilizzo dell'hash multiplo nel mondo reale è eccessiva. Nel tuo caso, sembra di esserlo. Nota che se usi diverse funzioni hash, non tutte avranno la stessa entropia, quindi questo riduce la forza dell'hash. Ad esempio, md5 ha meno entropia di sha1, quindi l'uso di sha1 su un md5 non migliorerà la forza dell'hash. La forza sarà generalmente uguale alla forza della funzione di hash più debole.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.