Domanda:
Perché le persone pensano che questo sia un cattivo modo per hash delle password?
genesis
2011-07-24 19:27:43 UTC
view on stackexchange narkive permalink

Bene, per favore dimmi cosa c'è di sbagliato in questo codice:

  $ password = "ciao"; $ password = md5 ($ password); per ($ i = 1; $ i<20 ; $ i ++) {$ password = md5 ($ password);}  

È esattamente uguale a questo:

  md5 (md5 (md5 ( md5 (md5 (md5 (md5 (mD5 (md5 (md5 (md5 (md5 (md5 (md5 (md5 (md5 (mD5 (md5 (md5 (md5 (‌ md5 ($ password))))))))))) ))))))))));  

e non credo che un utente malintenzionato con il mio DB sarebbe in grado di decriptare qualsiasi password con lunghezza> 2.

l'attaccante avrebbe dovuto decifrare questo elenco di hash MD5 per essere in grado di ottenere la password in chiaro:

  69a329523ce1ec88bf63061863d9cb140dcd649d4ef5f787e39ddf48d8e625a55d6aaee903365197ede6f325eb3716c5cbe8d0c48ab0ed8d23eacb1621f6c5c38fa852c5f5b1d0d6b1cb0fad32596c7191a84cf929b73800d2ff81da28834c6445b7d5e4d3fca6a4868d46a941076b72e5b7d9d10fef132829731255ef644319b3af6ff5f5c7ae757ca816a6cb62f092150f3682b2e58d1d0e1f789f9ba069823f76626950bf31dbc815c667ca4b2b4344f4c75517671e12946aab3c8c293f98442256b098b2d88e9 3428b08b51553087fd8ebc5bdff94f24a10decaa1ab64e8d04bbc863839b720d932a697f0bf443bde737c934db23c2d1d1026863e7583a8d745f6394700c4ab1e9ded0924ea35d2ce9428b51d3a63431c57a435423877b67017f40bdb4f1be1f5fae7dd0fc7b907  

e con forza bruta, si dovrebbe cercare 36 32 sup> (* 19) combinazioni, che è abbastanza unachivable; o mi sbaglio? Non è vero?

Vedi anche http://stackoverflow.com/questions/420843/need-some-help-understanding-password-salt
Perché è così brutto? 1) Non l'hai progettato prima di scriverlo. 2) Non sembrano esserci controlli di errore. 3) Non fornisci un controllo sulla sicurezza della password. 4) Non hai specificato le opzioni del compilatore o dell'interprete per un funzionamento sicuro. 5) Non hai fornito alcun vettore di prova. 6) Non è stato verificato e testato in modo indipendente.
Non 36 ^ 32. 16 ^ 32. Stai guardando il digest esadecimale dell'hash md5, quindi ci sono trentadue caratteri selezionati da un alfabeto di 16 caratteri (0-9, a-f) e non 36.
@drjimbob: aaah, è più desideroso di quanto pensassi! Potresti aggiungerlo come risposta? Mi piacerebbe accettarlo
@genesis, non per fare il pelo nell'uovo, ma l'ho fatto notare nella mia risposta circa due ore prima del commento del dr jimbob. http://security.stackexchange.com/questions/5586/why-do-people-think-that-this-is-bad-way-to-hash-passwords/5627#5627
perché hai bisogno di un minimo di 21 `md5 ()` nidificati. è la regola d'oro della crittografia! (sì, sto scherzando)
Quindici risposte:
#1
+76
Thomas Pornin
2011-07-24 20:00:48 UTC
view on stackexchange narkive permalink

Le cose sbagliate sul tuo metodo sono:

  • Usi troppe poche iterazioni (20 è troppo basso, dovrebbe essere 20000 o più): l'elaborazione della password è ancora troppo veloce, un attaccante con un PC di base sarà comunque in grado di "provare" decine di milioni di password al secondo.
  • Non c'è sale: un malintenzionato può attaccare diverse password con un costo per password molto basso, ad es. con tabelle precalcolate di password con hash (in particolare tabelle arcobaleno).
  • Stai inventando la tua crittografia. Non c'è niente di sbagliato nell'essere curiosi e cercare di capire le cose, ma poiché non esiste un test sicuro per sapere se un dato algoritmo è sicuro o meno, inventare la propria crittografia è spesso una ricetta per il disastro. Non farlo.

Quello che dovresti fare è usare bcrypt; c'è un'implementazione PHP nel framework di hashing delle password PHP portatile.

più iterazioni non portano una maggiore sicurezza. Più spesso si hash, maggiore è la probabilità di collisioni di hash. Direi che usare md5 due volte sarebbe meglio che usare md5 una volta, ma se lo usi 2, 20 o 20.000 volte non ha molta importanza. Usarlo due volte potrebbe essere migliore, poiché i siti Web di cracking standard come http://www.md5cracker.org/ non funzioneranno più.
Le collisioni di @moose: non sono un problema qui: lavoriamo sulla resistenza di preimage, non sulla resistenza alle collisioni, e questo è un bene perché MD5 è completamente rotto per quanto riguarda le collisioni comunque. La riduzione dello spazio di output _può_ essere vista come un problema, ma anche dopo 2 ^ 64 iterazioni, lo spazio dovrebbe comunque avere una dimensione di circa 2 ^ 64; il punto debole qui non è MD5, ma la password (cioè il cervello umano che può memorizzare una password). Le molteplici iterazioni servono a rendere gli attacchi _dictionary_ più costosi.
In realtà, il conteggio delle iterazioni nel software di oggi è molto più alto di 20000, a volte anche in milioni. Ma un consiglio solido non di meno.
@moose, non è corretto. Le collisioni non sono una preoccupazione qui; la probabilità di subire una collisione in questo contesto è trascurabile (come, meno delle possibilità di essere colpiti da un fulmine). Per i parametri sperimentati qui (iterando migliaia, milioni o miliardi di volte), più iterazioni * portano * maggiore sicurezza e la probabilità di collisioni è trascurabile.
@ThomasPornin Bcrypt è l'opzione migliore, è chiaro, ma per curiosità (situazione su cui non ho alcun controllo) 50 iterazioni di SHA-256 con salting sono efficaci? Perché o perché no? Ciò combatte le tabelle arcobaleno e le 50 iterazioni aumentano i costi di calcolo?
In realtà ho intenzione di contestare l'affermazione "Bcrypt è l'opzione migliore" che è stata lanciata (da @ThomasPornin e altri) qui.Bcrypt è migliore di PBKDF2 (che è solo salting e hashing iterato) perché richiede una quantità di memoria che non è * completamente * banale, ma è comunque facile da parallelizzare su hardware moderno.La RAM è economica in questi giorni.Scrypt o l'ancora più recente Argon2 (vincitore di una competizione triennale per il miglior algoritmo di hashing della password) sono migliori perché sono difficili da memorizzare e da calcolare, e la durezza della memoria è regolabile (il costo della memoria di Bcrypt è basso,e fisso).
#2
+34
Gordon Davisson
2011-07-27 06:25:52 UTC
view on stackexchange narkive permalink

Altri hanno descritto i limiti di questo metodo di hashing; Vorrei sottolineare un errore concettuale nella domanda:

Non credo che un utente malintenzionato con il mio DB sarebbe in grado di decifrare qualsiasi password con lunghezza> 2

L'attaccante dovrebbe decifrare questo elenco di hash md5 per poter ottenere una password semplice:

[elenco di risultati intermedi]

L'errore qui è pensare che la complessità dei risultati intermedi fornisce alcuna protezione contro un attacco di dizionario a forza bruta. Penso che il richiedente stia pensando che l'attacco deve funzionare all'indietro, a partire dall'hash memorizzato, e forza bruta a turno ogni risultato intermedio.

Questo non è affatto vero; ragionevoli attacchi al dizionario inizieranno con possibili password e attaccheranno l'intero stack di 20 hash contemporaneamente. Ecco lo schema dell'algoritmo:

  per ogni password candidata: hash 20 volte confronta con hash memorizzato  

Usandolo per controllare tutte le possibili password di 3 caratteri (assumendo stampabile ASCII) richiederebbe solo 20 * 95 ^ 3 = 17147500 hash, il che è fondamentalmente banale. L'uso di SHA-512 invece di MD5, nonostante abbia valori intermedi molto più grandi, sarebbe più sicuro solo perché ogni hash impiega un po 'più di tempo per essere calcolato.

tl; dr una funzione hash complessa non può salvarti se la password stessa non ha abbastanza entropia.

e come fa il cracker a sapere che deve eseguire l'hashish 20 volte?
@Enrique: il cracker potrebbe non saperlo, ma non dovresti contarci. Questo è [il principio di Kerckhoffs / la massima di Shannon] (http://en.wikipedia.org/wiki/Kerckhoffs%27_principle): il nemico conosce il sistema.
OK, ma allora è una buona idea hash X volte solo perché se il cracker non conosce X sarà più difficile per lui rompere l'hash. Ho sbagliato?
@Enrique: No, questo costringe semplicemente il cracker a confrontare dopo ogni hash, il che non lo rallenta molto. Dovresti eseguire l'hash molte volte (migliaia, non solo 20) in modo che il cracker abbia molto più lavoro per controllare ogni possibile password (vedi le risposte di Thomas e oliland).
@Enrique, Per essere chiari, MD5 è l'hash sbagliato per il lavoro. Usare bcrypt e regolare il parametro di ripetizione fino a quando l'operazione richiede `1ms` ** minimo ** è la strada da percorrere. (forse anche `100ms` non sarà un grosso problema se questo accade solo una volta per accesso) L'uso di bcrypt eviterà la necessità di installare la propria logica di ripetizione e un'altra caratteristica che è molto importante (a meno che non ci sia un numero limitato di utenti), vale a dire che ogni password ha il suo sale, richiedendo un lavoro di forza bruta per utente, invece di una volta per tutti gli utenti insieme.
#3
+17
oliland
2011-07-24 20:43:30 UTC
view on stackexchange narkive permalink

20x MD5 è un algoritmo di hashing veloce, il che significa che può generare password a una velocità sorprendente.

Smetti di usare algoritmi di hashing veloce per memorizzare le password. Anche con sali individuali; se qualcuno ha accesso diretto (in lettura: offline) al tuo database, possono essere calcolati molto facilmente.

Questo articolo spiega perché molto meglio di me:

http: / /codahale.com/how-to-safely-store-a-password/

L'articolo menziona pesantemente BCrypt (con un collegamento a una libreria PHP), ma tieni presente che ce ne sono altri algoritmi di hashing lenti che potrebbero essere adatti a te.

anche 19 * 36 ^ 32 combinazioni + lunghezza sconosciuta, caratteri, sale nell'ultimo hash md5 è male?
utilizzare un algoritmo a chiave simmetrica reversibile per crittografare la password è dannoso quasi quanto archiviare i dati in testo normale. Come se avessi compromesso il server, ci sono buone probabilità che tu abbia compromesso il codice / la chiave per decifrare i dati.
@dvhh - un MD5 non può essere invertito.
@Ramhound vecchio argomento, ma con i computer di oggi è possibile calcolare l'hash abbastanza velocemente per un dizionario o un attacco di forza bruta, ci sono persino tabelle precalcolate per testare le password non salate. Quindi sì, non può essere invertito, ma se sei abbastanza motivato, puoi scoprire l'input che corrisponde alla md5 abbastanza velocemente.
@dvhh dall'articolo: "bcrypt è un algoritmo di hashing della password adattivo che utilizza la pianificazione della chiave Blowfish, non un algoritmo di crittografia simmetrica."
#4
+11
deceze
2011-07-24 19:33:23 UTC
view on stackexchange narkive permalink

Il problema è che questo è un "algoritmo" abbastanza ovvio e abbastanza veloce da avviare.
È molto probabile che sia disponibile una tabella arcobaleno precalcolata per questo "algoritmo" e, anche se non esiste, md5 è abbastanza veloce da essere in grado di precalcolarne una in un lasso di tempo realistico.

Dovresti sempre utilizzare un salt individuale per ogni password per evitare questo tipo di attacco.

Ma di cosa avrebbe bisogno l'attaccante per ottenere rapidamente le mie password? E quanto tempo ci vorrebbe con il tavolo arcobaleno?
@gen Se hai una tabella arcobaleno per l'algoritmo "20xMD5", la ricerca di una password è istantanea.
@genesis Quanto tempo ci vorrà per decifrare una password? Controlla questo: http://md5hashcracker.appspot.com/
@deceze: esiste un tavolo del genere?
@gen Non posso darti un "sì" definitivo, poiché non lo so, ma penso che sia molto probabile.
@Chris: Quei "cracker" stanno solo usando una tabella di ricerca di coppie note (* input *, Hash (* input *)).
@deceze: Una tabella arcobaleno di oltre 30 caratteri. Non credo che esista. Almeno non completo
@Gumbo. Sì è vero. Ma la tavola cresce e cresce e cresce ...
1. Il fatto che l'algoritmo sia * "ovvio" * non è un problema di sicurezza. 2. Usare un salt è una buona idea, ma sono necessarie anche più iterazioni (e PBKDF2, bcrypt o scrypt sarebbero migliori).
@D.W. Quel "ovvio" in realtà è andato insieme alla frase successiva, che non è improbabile che esista già una tabella arcobaleno per un tale algoritmo.
Anche se non fosse "ovvio", e anche se non esistesse già nessun tavolo arcobaleno, sarebbe comunque una cattiva idea. Se il tuo algoritmo di hash della password è scadente, il fatto che nessun altro lo stia usando non rende OK usare l'algoritmo scadente.
@D.W. E sono totalmente d'accordo con questo, nel caso non fosse chiaro.
#5
+10
a CVn
2011-07-25 17:30:58 UTC
view on stackexchange narkive permalink

A parte ciò che è già stato sottolineato nelle altre risposte finora, mi sembra che tu abbia un malinteso fondamentale seduto proprio nella tua domanda. Lo spazio di output di una funzione hash a 128 bit come MD5 non è 36 ^ 32 (circa 6.3e49), ma 2 ^ 128 (circa 3.4e38). Sono 11 ordini di grandezza!

La crittografia è difficile. Se non sai esattamente cosa stai facendo (e in molti casi anche se lo fai), stai molto, molto meglio non provare a progettare qualcosa da solo ma piuttosto utilizzare un ready-made, soluzione collaudata. Per un esempio di vita reale di come le cose terribilmente sbagliate possono andare quando non sai esattamente cosa stai facendo, cerca la debacle della chiave Debian OpenSSL. La prima versione di Netscape PRNG è un altro esempio. Sono sicuro che ce ne sono anche molti altri, più o meno ampiamente pubblicizzati.

#6
+9
Joel Coehoorn
2011-07-24 23:51:55 UTC
view on stackexchange narkive permalink

Ci sono quattro problemi con l'iterazione ripetuta di md5, non importa quante volte lo fai.

Potenza di calcolo nel tempo

Il primo grosso problema qui è che come scritto che non si ridimensiona nel tempo per rimanere al sicuro man mano che i computer diventano più veloci. Ciò che è sicuro oggi verrà crackato in pochi istanti sui computer di domani.

I moderni algoritmi sicuri come bcrypt e scrypt sono stati ottimizzati in modo che l'algoritmo possa essere regolato automaticamente per essere più lento man mano che i computer attaccanti diventano più veloci. Dal momento che anche bcrypt è gratuito ed è ancora solo una semplice chiamata di funzione per te, non ci sono buone ragioni per non usarlo.

Ora, hai l ' inizio di una struttura di ridimensionamento integrato nel codice. Sarebbe facile eseguire il refactoring per eseguire l'hash md5 un numero arbitrario di volte, in modo tale da poterlo regolare in modo che sia più lento nel tempo. Ma non è abbastanza.

Progettato per fallire

Il secondo problema è che md5 è una scelta fondamentalmente scadente per un hash crittografico perché è stato specificamente progettato per essere veloce . Lo scopo di md5 è verificare o confrontare rapidamente file di grandi dimensioni. Per ottenere ciò, l'hash deve essere in grado di essere calcolato in modo rapido ed efficiente. Ciò significa che gli obiettivi di implementazione e progettazione dell'algoritmo sono completamente in contrasto con la memorizzazione delle password. Le possibilità che a un certo punto troveremo un modo per calcolare un hash md5 che è ordini di grandezza più veloce di quello che possiamo fare attualmente sono ordini di grandezza maggiori di quanto saremo in grado di fare lo stesso per sha1 o bcrypt.

Degenerazione

Il terzo problema è che gli algoritmi di hashing in generale tendono a man mano che li ripeti. Per capirlo, prendi il testo originale fornito dall'utente. La dimensione concettuale di questo testo è illimitata . C'è un numero infinito di valori possibili qui. Dopo aver hash il testo una volta con md5, siamo scesi a 2 128 numero di valori possibili ... ancora molto grandi, ma non più illimitati. Ma ripetiamolo di nuovo. md5 è buono, ma non è perfetto . Quei 340 undecillion potenziali input avranno alcune collisioni e produrranno un numero di risultati vicino, ma comunque leggermente inferiore a 2 128 . Man mano che continui a iterare, troverai più collisioni, fino a quando non finirai con un numero che, sebbene ancora grande, è significativamente inferiore allo spazio concettuale con cui pensavi di lavorare.

Cicli

Infine, il quarto problema è che alcuni dei tuoi potenziali input originali si tradurranno in cicli : valore numero 12345 hash a 98743, che hash a 67321, che hash di nuovo a 12345 e così via . In altre parole, alcuni input scorreranno lo stesso piccolo insieme di valori hash e ripetendoli ulteriormente non aiuterà . In effetti, più volte esegui l'hash, più è probabile che un dato input originale finisca in un ciclo.

Questo risale alla progettazione di md5. Un hash crittografico potrebbe essere progettato per ridurre al minimo (non eliminare del tutto, ma almeno ridurre al minimo) i fenomeni di degenerazione e ciclo, ma non era affatto un problema per md5.

Conclusione

Uno qualsiasi di questi motivi da solo è sufficiente per non utilizzare md5. Sono disponibili altre opzioni perfettamente buone e generalmente utilizzano la stessa interfaccia, quindi sceglierne una diversa non è difficile. In alcune piattaforme, è facile come cambiare un valore enum passato a qualche funzione "createhash". Metti insieme tutti e tre i motivi e continuare a usare md5 è assolutamente folle.

Citazione per le affermazioni secondo cui l'MD5 non è stato progettato con alcuna preoccupazione per la degenerazione o i cicli?MD5 è stato assolutamente progettato come una funzione hash crittografica.È considerato rotto (le collisioni sono facili, anche se la sua resistenza alla preimmaginazione ha retto ragionevolmente bene) ma affermando che `Un hash crittografico potrebbe essere progettato per ridurre al minimo la degenerazione e i fenomeni di ciclo [sic], ma non era affatto un problema per md5`necessita di backup.
#7
+7
Wedge
2011-07-25 07:56:57 UTC
view on stackexchange narkive permalink

Hai una semplice funzione di hashing unidirezionale per le password, sembra sicuro, vero? Dovresti fare molte ipotesi per forzare un sistema del genere. Tuttavia, considera uno scenario di caso negativo (nemmeno uno scenario peggiore). Utilizzi questo livello di sicurezza con un sito di importanza molto elevata, o anche un sito con molti utenti.

Poi, un giorno c'è un piccolo problema di sicurezza o il tuo sito ha una vulnerabilità precedentemente sconosciuta che viene sfruttata e tutti i dati del tuo account utente, comprese le password con hash, sono ora nelle mani dei "cattivi". I cattivi vanno al loro PC a basso costo con una GPU decente e modificano un programma esistente in precedenza per generare hash in modo che esegua 19 livelli di hashing md5. Quindi gli forniscono un dizionario ben affilato di password comuni e probabili, nonché stringhe alfanumeriche casuali di lunghezza crescente. Nel tempo la GPU procede a generare hash creando una tabella di ricerca. In qualsiasi momento i malintenzionati possono controllare la loro tabella di ricerca hash generata nell'elenco delle password con hash e, poiché non hai utilizzato un salt per password, trovare facilmente corrispondenze. Nel corso del tempo, mentre la GPU continua a funzionare, vengono rivelate sempre più password, fino a quando rimangono solo le password con la massima sicurezza.

#8
+6
dr jimbob
2011-07-25 23:03:08 UTC
view on stackexchange narkive permalink

MD5 non è il miglior hash da usare oggigiorno per la sicurezza al giorno d'oggi; gli hash possono essere calcolati troppo velocemente (sebbene il difetto più grande con md5 sia la facilità nel generare collisioni). Sono solo 128 bit (16 ^ 32 = 2 ^ 128 ~ 10 ^ 38); prova sha-256 (2 ^ 256 ~ 10 ^ 77; è 2 ^ 128 volte più chiavi) o sha-512. Il rafforzamento delle chiavi è una buona pratica (ad esempio, ci vuole 20 volte più tempo per generare una tabella arcobaleno); ma ancora 20 volte più a lungo non è così lungo (ad esempio, usa 20 macchine e ci vuole altrettanto tempo), ma è fatto meglio con un sale casuale. Sarebbe molto meglio rafforzare la chiave diciamo 100000 volte.

  $ password = "ciao"; $ salt = random_str (); // genera uno str $ password = sha256 ($ password); per ($ i = 1; $ i<100000; $ i ++) {$ password = sha256 ($ salt + $ password);} $ sep = "|" ; $ password_scheme = "SHA256x100k"; $ password = $ salt + $ sep + $ password_scheme + $ sep + $ password;  

Utilizzo di un linguaggio pseudo-codice dove + concatena stringhe e random_str () è una funzione che genera una breve stringa casuale. Lo scopo del salt casuale è che se un utente malintenzionato vede il tuo codice sorgente, vede gli hash delle tue password, deve generare una tabella arcobaleno separata per ogni sale diverso (o una per ogni password). Quindi ora, invece di dover generare solo una tabella arcobaleno per ottenere tutte le password degli utenti, devono generare una tabella arcobaleno per ottenere una sola password. Inoltre è una buona idea documentare lo schema della password nell'hash, quindi puoi aggiornarlo se necessario, ad esempio, migrare da SHA256x100k a SHA256x1k se hai bisogno di utilizzare meno CPU o decidi di passare a un hash diverso in un secondo momento.

Certo, non è la migliore idea inventare il tuo metodo di crittografia personalizzato se non sei un esperto di crittografia. Lascerai sicuramente l'opportunità di sottili falle di sicurezza come tempismo degli attacchi anche con algoritmi apparentemente sicuri. bcrypt è probabilmente la soluzione migliore.

Nota: MD5 è particolarmente vulnerabile agli attacchi di collisione, ma non devi davvero preoccuparti delle collisioni negli attacchi preimage (che è il metodo di attacco contro gli hash delle password). Un utente malintenzionato ha ottenuto un elenco di hash delle password (h) in qualche modo e ha imparato la routine hash (md5 x 20 o salted sha256 x 100k) e sta cercando di ottenere qualsiasi messaggio m, tale che hash_routine (m) = h, per lasciarglielo fare nel tuo sistema.

La vulnerabilità di collisione di cui ti preoccupi è che se hai un hash (m1) = hash (m2) quando m1! = m2; quindi se scarichi qualcosa in cui le persone hanno controllato che il file m1 sia sicuro e vuoi assicurarti di aver effettivamente scaricato m1, confronta hash (m1) con l'hash pubblico md5. Se esiste una versione dannosa m2 con lo stesso hash md5, non puoi essere sicuro che m1 sia sicuro controllando la sua somma md5.

È probabile che l'entropia di input (nella password) sia inferiore allo spazio di output grezzo della funzione hash, quindi cambiare le funzioni hash * solo * a causa della dimensione dell'hash di output non farà una differenza drammatica in termini di sicurezza.
@Michael, Sono d'accordo. Il vantaggio principale di SHA-256/512 è che è più lento. Per arrivare a 128 bit di entropia avresti bisogno di una password complicata come 22 caratteri casuali da una tastiera da 62 caratteri; ad es. pvLfXpJ4qbgSEBohcmZyvz; una password di 8 caratteri avrebbe solo ~ 47 bit di sicurezza (e avresti bisogno di 43 caratteri per 256 bit). Anche se probabilmente è precauzionale, per alcune applicazioni sicure le persone potrebbero voler utilizzare password folli e con il costo dello spazio su disco al giorno d'oggi non c'è motivo di salvare i byte. (Ad esempio, crypt in / etc / shadow tende a usare sha-256/512 oggigiorno).
#9
+5
Jeff Ferland
2011-07-24 20:56:17 UTC
view on stackexchange narkive permalink

Le tabelle arcobaleno funzionano perché più sistemi utilizzano schemi simili per la gestione dei dati. Sebbene sia noto che l'aggiunta di un sale dovrebbe essere una caratteristica universale dell'hashing delle password, l'aggiunta di un numero di round aiuta anche a sconfiggere i tavoli arcobaleno. Vale a dire: una tabella arcobaleno per qualsiasi sottoinsieme di caratteri in MD5 non può risultare in una corrispondenza per alcuna password nel sistema tranne che per collisione accidentale. La funzione di riduzione della tabella arcobaleno convertirà ogni hash generato in una stringa che corrisponde alla lettera, al numero e al modello di simboli per cui è progettata la tabella. Nel momento in cui un hash viene generato dal tuo metodo che include un simbolo al di fuori di tale intervallo (una certezza virtuale in quanto l'input della tua funzione hash è l'uscita di un hash), impedirà alla tabella di funzionare.

Il fatto che il tuo sistema sia semplice o anche pubblicamente noto non importa tanto quanto il fatto che sconfiggere una tabella arcobaleno richiede solo che i tuoi hash non possano essere stati creati in gran numero con il metodo utilizzato per generare quella tabella.

soluzione discussa era la chiave che si estendeva ai diversi metodi. Per calcolare una password lì, viene cercata la versione del metodo hash e la password calcolata in base a quella. Dopo il login con una vecchia versione hash, verrebbe aggiornato alla versione più recente.

Thomas ha detto che dovresti usare più round per il tuo hashing. Ciò di cui non si è parlato è come determinare quanti round utilizzare. La risposta a questa domanda è sfocata, ma fondamentalmente si riduce a "Quante iterazioni posso eseguire per il caricamento del login sul mio sistema?" Se hai 10.000 utenti che accedono ogni minuto, potresti essere disposto a dedicare un carico della CPU del 25% a questo. Per questo, scegli un numero di iterazioni che ti consenta di eseguire circa 700 calcoli al secondo.

L'esercizio mentale per determinare se una tabella arcobaleno per 25 iterazioni hash coprirà un sistema che ha 20 iterazioni hash implica un lavoro mentale che non sono disposto a fare domenica mattina, ma se qualcuno vuole intervenire sull'idea, quello essere apprezzato.
Una tabella arcobaleno può ripagare solo se devi attaccare un certo algoritmo di hashing della password più di una volta. Il tempo impiegato per la funzione di riduzione e il tempo perso per generare sovrapposizioni rendono l'ipotesi sequenziale più efficiente e con maggiori probabilità di successo (una percentuale di hash mai raggiunta dalla progettazione).
Le tabelle arcobaleno forniscono vantaggi quando voglio crackare le password su una macchina, quindi decifrare le password su un'altra macchina in un secondo momento e utilizzare quella scritta su disco per un compromesso di tempo. Se lo userò solo una volta (o anche 2-3 volte a causa dell'inefficienza della generazione di catene), allora non vale la pena costruire prima l'intera tabella. Il vantaggio di più istanze dello stesso hash appare solo quando vengono attaccate in momenti diversi nel tempo. Quello che ho menzionato nel mio ultimo commento era cercare una semplice ricerca che sarebbe stata utilizzata nella normale forzatura bruta.
Jeff, OK, prima ho frainteso quello che stavi cercando di dire. Scusate. Forse quello che stai cercando di dire è che se nessun altro ha creato una tabella arcobaleno per questo metodo hash, allora non posso riutilizzare il lavoro di qualcun altro per precalcolare la tabella arcobaleno. Ok capito. Continuo a pensare che sia fuorviante trarre vantaggio da questo discutibile vantaggio quando lo schema ha tanti problemi di sicurezza più seri. E (questione a parte) non sono sicuro che sia impossibile riutilizzare le tabelle arcobaleno esistenti (come suggerisci), o che sia una buona idea distribuire un meccanismo di sicurezza supponendo che solo un sistema lo utilizzerà.
Destra. Devo tornare indietro e riformulare la mia risposta nei prossimi giorni perché ovviamente ha causato confusione (giusto non importa se un gruppo di persone informate non capisce quello che ho detto). Buona discussione, in un certo senso.
#10
+4
Frog
2011-07-24 19:47:22 UTC
view on stackexchange narkive permalink

No, ti sbagli. Il problema con gli hash md5 è che c'è una possibilità relativamente grande di collisioni: ci sono molte stringhe che generano lo stesso hash. E poiché ci sono solo 36 ^ 32 possibilità, che possono essere provate in circa 35 ore credo (e otterrà un risultato molto prima perché c'è una grande possibilità di collisioni), non è più considerato un buon hash. Per non parlare del fatto che probabilmente esiste una tabella arcobaleno per 20 hash md5. Inoltre, ci sono persone che dicono che md5 è effettivamente reversibile, ma non ne sono sicuro.

Ci sono due modi per rendere le tue password più difficili da hackerare:

  1. Usa un sale statico. Questo fondamentalmente rende le tabelle arcobaleno inefficaci, perché l'hacker non può più usare solo parole inglesi, dal momento che il tuo sale (che si spera non conosca l'hacker) costituisce gran parte della stringa. Prova i sali lunghi composti da molti caratteri speciali;
  2. Usa un algoritmo di hashing migliore e più lungo come whirlpool o sha512. Questo ovviamente aumenta notevolmente la quantità di possibilità;
  3. Hash la tua stringa più (x) volte. Questa è una delle cose che hai fatto bene: se l'hacker conosce il tuo sale e la quantità di volte che hai hash (quindi fondamentalmente ha accesso al tuo codice sorgente e al tuo database), questo assicura che impieghi x volte più tempo per ottenere risultati ;
  4. Crea un salt dipendente dalla stringa. Questo è un salt generato casualmente per ogni stringa salvata nel database e memorizzata insieme ad essa. Questo assicura che l'hacker debba ripetere ogni possibilità dell'hash per ogni password, invece di poterlo fare una volta per ogni password che hai memorizzato. Se hai 500 password memorizzate nel database, in questo modo l'hacker impiega 500 volte più tempo per hackerare tutte le password.

Spero che questo abbia aiutato. :)

Scusa, non ho pensato a 20x hash md5, quindi non è 36 ^ 32 ma 19 * 36 ^ 32 + lunghezza sconosciuta, caratteri, sale nell'ultimo hash md5. Ho ragione?
Intendi dire che pensi che la quantità di possibilità aumenti quando fai più hash? No, non è vero: ci sono 36 ^ 32 possibilità, perché è solo la quantità di stringhe diverse che puoi ottenere nella lunghezza di 32 caratteri. Quindi l'hashing 20 volte non protegge dalle collisioni, ma si assicura che ci vuole molto più tempo all'hacker per provare tutte le possibilità. Quindi è meglio è.
Uffa. Un hash md5 (in formato hexdigest) ha trentadue caratteri esadecimali (16 scelte: 0-9 e a-f). Quindi 16 ^ 32 = 2 ^ 128 ~ 3,4 x 10 ^ 38 hash md5 univoci, non 36 ^ 32 (presumo che tu abbia pensato 10 cifre, 26 caratteri). Se disponi di una configurazione con un milione di processori in grado di generare hash per miliardi di input al secondo, ci vorrebbero comunque ~ 10 ^ 16 anni per creare hash per tutti gli hash iniziali in stile 2 ^ 128 md5. Sarebbe molto meglio ottenere solo un elenco di password probabili (tale elenco è molto più breve (diciamo 10 ^ 12 password) e un cluster potrebbe generare la tabella arcobaleno necessaria in pochi secondi).
@Frog, la tua risposta contiene una serie di errori. La tua affermazione sulle collisioni non è corretta: in questa applicazione, la possibilità di una collisione è minima. Inoltre, ci sono altri errori nella tua risposta (ad esempio, 36 ^ 32 non è corretto; l'uso di sha512 o whirlpool non fa molta differenza e la lunghezza dell'output della funzione hash non ha importanza; usare un il salt statico non è una buona idea, dovresti invece usare un salt casuale scelto indipendentemente per ogni password da sottoporre ad hashing).
@D.W .: Anche un piccolo miglioramento fa la differenza, quindi è sempre meglio usare sha512 o whirlpool invece di md5. Penso che usare un salt statico sia una buona idea, perché in questo modo l'hacker ha bisogno di accedere sia al codice sorgente che al database, mentre altrimenti l'accesso solo al database è abbastanza buono.
@Frog, no, non è corretto. Non vi è alcuna differenza di sicurezza significativa a causa di un output hash a 128 bit rispetto a un output hash a 512 bit. Non è nemmeno un piccolo miglioramento; il miglioramento è statisticamente indistinguibile da zero. L'affermazione * "Questo ovviamente aumenta notevolmente la quantità di possibilità" * è semplicemente sbagliata. Per quanto riguarda il sale, se hai un sale per utente, non c'è valore aggiunto di un sale statico. Se non hai un sale per utente, sei nei guai e un sale statico non ti tirerà fuori dai guai. Quindi, in entrambi i casi, il sale statico è inutile.
#11
+2
Gumbo
2011-07-24 19:53:22 UTC
view on stackexchange narkive permalink

In generale, non c'è niente di sbagliato nell'hashing di un valore più volte per renderlo più robusto contro gli attacchi di forza bruta. In effetti, questa è una tecnica già applicata nota come key stretching.

L'unica obiezione al tuo esempio è che dovresti usare un algoritmo di hashing crittograficamente forte così come lo schema di hashing che include un sale per maggiore entropia e resistenza agli attacchi della tabella arcobaleno. Nella migliore delle ipotesi uno schema di archiviazione delle password già collaudato come crypt che è stato progettato specificamente per le password.

#12
+2
yfeldblum
2011-09-28 06:38:37 UTC
view on stackexchange narkive permalink

Non credo che l'attaccante ... sarebbe in grado di

Stai assumendo di sapere come funzionano gli attaccanti.

Stai assumendo conosci tutti i trucchi usati dagli aggressori e che ti sei difeso con successo da ognuno di essi.

Stai assumendo che non ci sia nulla nella ricerca pubblicata, conoscenza che è disponibile per chiunque abbia voglia di imparare, questo potrebbe aiutare anche un utente malintenzionato moderatamente abile a violare la sicurezza.

Stai presumendo che l'attaccante non sia nemmeno disposto a eseguire un attacco di forza bruta con computer rubati. (Hai considerato lo scenario in cui un utente malintenzionato è paziente e avvia un lavoro in background sul server di qualcun altro, un server in cui l'attaccante ha violato e non sta pagando, allo scopo di violare il file della password per un periodo di un mese? ?)

Questo di solito è un presupposto molto negativo .

#13
+1
goodguys_activate
2011-10-31 20:58:47 UTC
view on stackexchange narkive permalink

Link correlati:

#14
  0
Ibu
2011-09-28 04:36:24 UTC
view on stackexchange narkive permalink

Capisco che questa domanda è già qui da un po 'di tempo e ha delle risposte eccellenti. Comunque penso che ci sia un problema che non è stato affrontato. Utilizzare un algoritmo potente (da una libreria) è la strada da percorrere, poiché questi metodi sono stati testati. Ma ecco cosa vedo:

Non credo che un utente malintenzionato con il mio DB sarebbe in grado di decrittografare qualsiasi password con lunghezza> 2

Il il problema non è creare l'algoritmo più impossibile da decriptare. Il problema è proteggere il database. Ad esempio, se l'aggressore ha una presa sul tuo database, non credo che gli interesserà molto le password in esso contenute.

In realtà, le password vengono spesso riutilizzate tra più siti Web. Quindi una password per un sito web non è utile solo per questo sito stesso, ma anche per altri.
#15
-5
dvhh
2011-07-25 07:42:22 UTC
view on stackexchange narkive permalink

Il problema con il tuo metodo è che con ogni chiamata su md5 stai allargando lo spazio di collisione delle tue password ( nessuna prova matematica al riguardo, solo comprensione ingenua ). Per quanto possa sembrare interessante, non cercare di rendere la tua sicurezza più complicata del necessario. Il concatenamento di algoritmi di hashing è valido come usare più pseudo casuali per provare a generare un casuale sicuro. Potresti ottenere una sicurezza semplice che sia abbastanza sicura se applichi la pratica del buon senso.

In ogni caso, usa il sale usa un algoritmo di hashing che abbia uno spazio di collisione abbastanza grande. Se vuoi più sicurezza dovresti considerarli ad altri livelli, come la sicurezza del server, la gestione della sicurezza del personale.

Comunque, se vuoi applicare altri consigli sull'uso di bcrypt ( che è tanto dannoso quanto richiede per ottenere la chiave per decifrare l'intero elenco di password [ O (n) una volta ottenuta la password], contro la ricerca di una tabella arcobaleno contro ogni voce [ O (n * m) ]), ti consiglio almeno di utilizzare un cifrario a chiave pubblica poiché la chiave per decrittografare i tuoi dati non sarebbe necessaria nella verifica dell'input (utilizza la chiave per crittografare nello stesso modo in cui effettui l'hashing dei dati).

bcrypt non è un meccanismo di crittografia simmetrica. È un sistema di archiviazione delle password unidirezionale che utilizza un codice a blocchi simmetrico nell'implementazione. Per controllare una password usando bcrypt non decifrare nulla. Il concatenamento degli hash va bene e non allarga lo spazio di collisione.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...