E 'più sicuro cancellare una password più volte?

39

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

Credo che la prima domanda sia "è corretto?" In caso contrario, per favore, respinga 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 ridisegnato (possibilmente con qualcosa aggiunto) tutto quello che posso vedere è che c'è una riduzione nel limite superiore della "unicità" finale ... che è legato a l'input iniziale.

Lasciatemelo dire in un altro modo: abbiamo x il numero di stringhe che, quando sono hash, sono ridotte a possibili stringhe. Vale a dire, ci sono collisioni nel primo set. Ora che arriva dal secondo set al terzo, non è possibile che si verifichi la stessa cosa (cioè collisioni nell'insieme di tutte le possibili stringhe y che risultano nello stesso hash nel terzo set)?

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

Forse un esempio spiegherà le mie divagazioni? Prendi "hash_function_a" che darà "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à "1" e "2" l'hash "3". Se dovessi usare it come "hash secondario" dopo "hash_function_a", anche se la password è "a", potrei usare "b", "c" o "d".

Oltre a tutto ciò, ho capito che i sali dovrebbero essere usati, ma in realtà non cambiano il fatto che ogni volta che mappiamo gli input "x" a "meno di x". Non penso.

Qualcuno può spiegarmi che cosa mi manca qui?

Grazie!

EDIT: per quello che vale, io non lo faccio da solo, io uso bcrypt. E non sono molto preoccupato se sia utile o meno per "usare i cicli" per un "hacker". Mi sto davvero chiedendo se il processo riduce o meno la "sicurezza" dal punto di collisione dell'hash.

    
posta Narcissus 20.10.2011 - 19:52
fonte

6 risposte

25

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

Il problema con

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

è che questo è strong solo quanto la funzione hash più debole della catena. Per esempio se hashn (l'hash più interno) dà una collisione, l'intera catena di hash darà una collisione ( indipendentemente da quali altri hash ci sono nella catena ).

Una catena più strong sarebbe

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

Qui evitiamo il problema di collisione iniziale e generiamo essenzialmente un sale che dipende dalla password per l'hash finale.

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

    
risposta data 20.10.2011 - 20:18
fonte
51

L'utilizzo di algoritmi di hashing diversi è una cattiva idea - ridurrà l'entropia piuttosto che aumentarla.

Tuttavia, supponendo che tu abbia un algoritmo di hashing crittograficamente strong e un buon salt, applicando la stessa funzione di hash diverse volte il processo di hashing è più costoso dal punto di vista computazionale. Il vantaggio di questo è che quando altri metodi di cracking dell'hash della password non riescono (indovinando, attacchi di dizionario, tabelle arcobaleno, ecc.) E l'hacker viene forzato in tecniche di forza bruta, impiega più tempo a provare ciascuna password, semplicemente perché devono applicare la stessa funzione di hash più spesso. Quindi, se un round di hashing richiederebbe un mese di forzatura bruta, applicarlo dodici volte aumenterebbe il tempo stimato a un anno.

Gli algoritmi di hashing recenti come bcrypt si basano su questa idea; contengono un parametro per controllare la complessità computazionale dell'hash, in modo da ridimensionarlo man mano che le velocità dell'hardware progrediscono: quando l'hardware diventa più veloce di un fattore due, si aumenta la complessità per compensare, quindi il tempo richiesto per forzare la forza gli hash rimangono approssimativamente costanti.

    
risposta data 20.10.2011 - 22:08
fonte
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.

Dovresti utilizzare un'implementazione ben consolidata dell'hash della password che a sua volta dovrebbe utilizzare una funzione di derivazione della chiave ( KDF ) come come PBKDF2, bcrypt, scrypt o il più recente Argon2.

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 cancellato la password più volte, usando lo stesso algoritmo ogni volta. Non ha senso usare l'algoritmo di digest message message, come sottolineato da altri.

    
risposta data 15.10.2013 - 11:58
fonte
2

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).

    
risposta data 20.10.2011 - 20:10
fonte
-1

La mia comprensione è che l'utilizzo di più algoritmi di hashing consiste nel sconfiggere tabelle arcobaleno . Anche l'utilizzo di un buon sale funziona, ma suppongo che sia un secondo livello di protezione.

    
risposta data 20.10.2011 - 20:36
fonte
-1

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

Questo va in questo modo. Il valore memorizzato è hash ^ n (pass) nel computer A. A chiedere a B di autenticare e dare a B l'intero n. B esegue il calcolo hash ^ (n-1) (pass) e lo rimanda a A.

Verifica che hash (hash ^ (n-1) (pass)) == hash ^ n (pass). Se è vero, allora l'autenticazione è fatta. Ma poi, Un archivio hash ^ (n-1) (pass) e successiva autenticazione, daranno B n-1 invece di n.

Questo garantisce che la password non venga mai scambiata in chiaro, che A non sappia mai quale sia la password, e che l'autenticazione sia protetta da replay. 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 di hash multipli è lo strumento HMAC, per garantire l'autenticazione e l'integrità di una richiesta. Per ulteriori informazioni su HMAC, consulta link .

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

    
risposta data 20.10.2011 - 21:29
fonte

Leggi altre domande sui tag