Qual è il problema con l'hashing a catena?

10

Diciamo che la mia password è un singolo carattere: "a".

Non potrei incatenarlo a 1000 (o più) volte e renderlo quasi invulnerabile agli attacchi dei tavoli arcobaleno e alla forza bruta?

Perché non è preferibile la salatura e quali sono i problemi con questa tecnica, se esiste?

MODIFICA: chiarimento: per catena di hash intendo hashing hash 1000 volte.

    
posta dee-see 31.01.2012 - 02:54
fonte

5 risposte

19

Per rafforzare un hash per le password, devi fare due cose nel processo di hashing:

  1. per renderlo unico;
  2. per rallentare.

"Unico" significa che ogni password deve essere sottoposta a hash con la propria funzione di hash; quale hash è usata può essere qualche informazione pubblica (cioè memorizzata lungo il valore hash), ma tu vuoi renderla diversa per ogni password che hai. Questo è ciò che fa salt : il sale definisce la procedura di hash da utilizzare, tra una famiglia ampia. L'unicità sconfigge le tabelle arcobaleno: le tabelle arcobaleno, come tutti gli altri tipi di tabelle precalcolate, si basano sull'idea che valga la pena passare un po 'di tempo a digitare un sacco di password e memorizzare i valori hash (possibilmente in modo intelligente che consente una compressione estrema , come le tabelle arcobaleno), perché la tabella risultante può essere utilizzata per attaccare diverse password, con un costo marginale per password molto piccolo. Con i sali, ogni password ha una sua funzione, quindi la tabella è valida solo per una sola password, il che ne distrugge i vantaggi.

Hashing "1000 (o più) volte" la password non include un salt, e, come tale, è vulnerabile alle tabelle precalcolate. Ad esempio, supponendo SHA-256 come funzione hash, ecco la tua password con hash:

f3f19029aa4ef4bde723f49b4e90a7ad51473c54a03589af6fef706bf50d7894

Questo è l'hash SHA-256 di 1000 caratteri "a". Potrei precomprimere quel valore perché una volta che hai detto "1000" hai detto tutto; niente sale, quindi nessuna sorpresa per l'aggressore.

Lentezza significa rendere ogni password indovina il più costoso possibile per l'attaccante. Anche con una buona salatura, una singola password con hash può essere vulnerabile alla forza bruta, ovvero " attacco di dizionario " (cercando potenziali password), perché gli umani non sono così fantasiosi quanto i computer sono potenti. Un PC con una GPU può calcolare una funzione hash un miliardo di volte al secondo. Vogliamo una procedura di hashing che richiede più tempo per il calcolo - non troppo, perché il nostro server onesto avrà anche le password di hash quando un utente effettua il login e non abbiamo neanche una CPU infinita; ma abbiamo solo bisogno di hash, al massimo, una dozzina di password al secondo, quindi possiamo tollerare una funzione hash sostanzialmente lenta.

Solitamente, la lentezza si ottiene imponendo l'hashing nidificato: abbiamo cancellato la password, quindi abbiamo cancellato il valore hash risultante, che abbiamo nuovamente cancellato e così via. Ci sono alcuni dettagli complicati su come e dove viene inserito il sale. Hashing della concatenazione di 1000 volte (in realtà, con le cifre sopra, 1 milione di volte sarebbe meglio) la password (o la concatenazione della password e del sale) potrebbe servire allo stesso scopo, ma è un po 'delicato in pratica: infatti, vogliamo configurare il numero di ripetizioni della password in modo che la procedura sia tollerabilmente lenta. Ma con un tale sistema, l'hashing di una password di 40 caratteri richiede 40 volte il tempo di hashing di una password di 1 carattere; se quest'ultimo deve essere lento, il primo sarà 40 volte più lento, il che diventa presto intollerabile. Con l'hashing nidificato, è più semplice ottenere un tempo di hashing costante, che semplifica la configurazione.

E, naturalmente, fatto in casa è Bad . Inserire una password e un sale in una funzione hash, iterata e / o annidata, è sottile; ci sono insidie e, peggio di tutto, non puoi sapere se hai sbagliato o no. La sicurezza non può essere verificata in modo affidabile. Pertanto, dovresti rispettare gli standard di buona reputazione pubblicati e ampiamente implementati, come bcrypt e PBKDF2 . Se solo perché significa che qualsiasi contrattempo non sarà il tuo difetto.

    
risposta data 31.01.2012 - 13:11
fonte
5

Il rafforzamento / allungamento della chiave è una buona tecnica (anche se un 1000 non ti compra molto con gli hash semplici - md5 / sha1 può essere calcolato ad un ritmo di ~ 1 miliardo al secondo per gpu).

Per semplicità, ti darò un esempio concreto. Hai un'app Web e presumo che l'avversario malintenzionato sia riuscito ad accedere al tuo server. Potrebbe trattarsi di un amministratore che è segretamente malvagio, qualcuno che ha fatto irruzione nella tua stanza dei server, un bidello che ha le chiavi o un hacker casuale che è riuscito a sfruttare qualche exploit per entrare.

L'avversario prima riesce a esportare i nomi utente memorizzati e i loro hash di password dal tuo database. Quindi guardano il codice in esecuzione del tuo server web per come controlla le password. Vede qualcosa nella sezione di autenticazione del tuo codice web server che assomiglia a:

def check_password(username, password_to_check):
    if is_username_in_db(username):
        already_failed = False
        hash_from_db = get_password_hash_from_db(username)
    else:
        already_failed = True
        hash_from_db = get_password_hash_from_db('some_known_user')
    i = 0
    computed_hash = password_to_check
    while i < 1000:
        computed_hash = compute_sha1_hash(computed_hash)
        i += 1
    if strcmp(computed_hash, hash_from_db) and not already_failed:
        return True
    else:
        return False 
 # As an aside note a successful case takes the same amount of cpu time as a failing case, 
 # so timing attacks do not reveal that users exist; 
 # you should also make sure that 'strcmp' (string comparison) doesn't fail prematurely.

Gli aggressori dicono aha! le password nel db sono hash 1000 volte e non salate. Quindi generano hash a un tasso di un miliardo al secondo (quindi puoi controllare un milione di password in un secondo) con la loro moderna gpu. Quindi, in circa 1 giorno di tempo computazionale gpu, hanno ottenuto hash per 86,4 miliardi di password (36 bit di entropia) e costruito una tabella arcobaleno sul loro disco fisso di terabyte.

Quindi cercano tutti gli hash nella tabella arcobaleno e trovano molte corrispondenze; ora con la password in chiaro e il nome utente, cercano di entrare in altri servizi di quegli utenti in cui possono avere password riutilizzate. Se le password fossero state salate in modo univoco, avrebbero dovuto generare una nuova tabella arcobaleno per ogni password rendendo l'attacco a forza bruta molto meno efficace (ad esempio, un giorno o più di tempo GPU per forzare la forza bruta su ogni password semplice).

    
risposta data 31.01.2012 - 23:59
fonte
1

Perché è non invulnerabile al forzante bruto. Per trovare la password sulla falsariga di un 'hash' un migliaio di volte tutto quello che devo fare è provare 52000 hash (o molto meno se la password è effettivamente 'a' perché inizio solo all'inizio dell'alfabeto), che è terribilmente facile da fare.

    
risposta data 31.01.2012 - 04:01
fonte
1

Se si tratta di una semplice parola del dizionario, la funzione dovrebbe essere molto lenta per bloccare qualsiasi attacco non banale. Ogni programma decente proverà prima le password popolari / le password brevi / i modelli semplici. Quindi hai tutti i problemi pre-calcolati che altri hanno menzionato sopra. Dai uno sguardo allo schema di FreeBSD MD5 come un esempio decente di come prendere un vecchio MD5 scadente e renderlo piuttosto resiliente al cracking.

    
risposta data 01.02.2012 - 03:31
fonte
1

L'hashing a catena non ti protegge dall'uso delle tabelle arcobaleno.

    
risposta data 08.02.2012 - 13:40
fonte

Leggi altre domande sui tag