L'hashing sul lato client può ridurre il rischio di negazione del servizio con gli hash lenti?

28

Quando si memorizzano le password dell'utente che è necessario verificare (ma non utilizzare come testo normale) lo stato attuale della tecnica è:

  1. Hash la password
  2. Utilizza un sale
  3. Utilizza una funzione hash lenta - bcrypt, scrypt, ecc.

Fornisce la migliore protezione possibile contro un utente malintenzionato che ha rubato il database delle password. Non risolve altri problemi come phishing, malware, riutilizzo delle password, ecc.

Ma c'è un problema rimanente: la lenta funzione hash può consentire un attacco denial of service . Una singola richiesta brucia molta CPU, il che rende possibile un DOS con un numero relativamente piccolo di richieste simultanee, rendendo difficile l'uso di difese come la limitazione IP.

Dato il miglioramento delle prestazioni di JavaScript nei browser, potrebbe ora avere senso farlo nel browser. Presumo qui che il sito stia utilizzando SSL, quindi il JavaScript viene consegnato in modo sicuro. Se non stai utilizzando SSL, è improbabile che l'utilizzo di una funzione hash lenta sia una priorità per te. Esiste almeno una implementazione JavaScript di bcrypt. Ma usando questo in un modo semplice introdurrebbe due problemi:

  1. Il client deve recuperare il sale dal server. Questo introduce la latenza all'accesso e, a meno che non si prenda cura, può rivelare se esiste un particolare account utente.
  2. Se l'hashing viene eseguito esclusivamente sul client, i vantaggi dell'archiviazione degli hash vengono persi. All'attaccante che ha rubato gli hash delle password può semplicemente accedere utilizzando gli hash.

Tuttavia, penso che ci siano soluzioni accettabili per entrambi questi problemi:

  1. Il sale può essere generato come hash (server_salt + user_name) - dove server_salt è un numero casuale che è univoco per il server, pubblico, e lo stesso per tutti gli utenti. L'hash risultante sembra avere le proprietà richieste di un sale.
  2. Il server deve eseguire una singola operazione di hash veloce sull'hash che riceve. Ad esempio: il server memorizza SHA-256 (bcrypt (salt, password)). Il client invia bcrypt (salt, password), quindi il server applica SHA-256 e controlla l'hash. Questo NON consente a un utente malintenzionato di condurre un attacco brute offline veloce. Possono fare una forza bruta veloce di SHA-256 (password) perché la password ha una quantità limitata di entropia - 2 ^ 50 o 2 ^ 60 o giù di lì. Ma un bcrypt a 128 bit (sale, password) ha entropia o 2 ^ 128, quindi non possono facilmente forzarlo.

Quindi, questo è un approccio ragionevole e sicuro?

Sono consapevole del consiglio generale di "non tirare la tua cripto". Tuttavia, in questo caso, sto tentando di risolvere un problema che non è risolto dalla crittografia predefinita. Per alcune credibilità di base, questo è stato osservato da John Steven ( un esperto riconosciuto nel campo) con esito positivo da un'analisi "breve".

    
posta paj28 25.05.2014 - 20:31
fonte

2 risposte

23

L'uso di servername + username as salt (o di un hash) non è l'ideale, in quanto porta al riutilizzo di sale quando si cambia la password (dato che si mantiene il proprio nome e si parla ancora allo stesso server). Un altro metodo è ottenere il sale dal server come fase preparatoria; questo implica un roundtrip extra client-server, e significa anche che il server troverebbe più difficile nascondere se un determinato nome utente esiste o meno (ma non importa molto nella pratica).

Ciò che descrivi è un'idea ben nota, solitamente chiamata relief server , che può essere applicata a qualsiasi funzione di hashing della password nel modo in cui descrivi:

  • Il cliente ottiene (o calcola) il sale.
  • Il client calcola il valore hash lento V e lo invia come password.
  • Il server memorizza h (V) per una veloce funzione hash h e lo usa per verificare il valore V dal client.

Questo è sicuro. Lo svantaggio principale è che l'hashing lento andrà alla velocità del client, quindi il numero di iterazioni potrebbe dover essere abbassato, possibilmente considerevolmente, quindi se il client è computazionalmente debole - come nel caso di qualsiasi cosa coinvolge Javascript. Se il sistema deve funzionare con un browser su uno smartphone non recente, allora il conteggio delle iterazioni dovrà essere da 10 a 100 volte più piccolo di quello che potrebbe essere fatto sul server, implicando una corrispondente riduzione della resistenza alla forza bruta (in nel caso in cui l'attaccante rubi i valori dell'hash memorizzati sul server).

Questo è un compromesso: dal momento che gli offload del server occupato funzionano sui client, può utilizzare un numero di iterazioni più elevato senza se stesso annegando sotto il carico; ma poiché i client sono deboli, il conteggio delle iterazioni deve essere abbassato, di solito molto più di quanto è stato aumentato grazie allo scaricamento; questo significa che la costruzione non vale lo sforzo. Di solito.

Naturalmente, se i clienti sono computazionalmente forti, ad es. questa è un'applicazione di codice nativo su una macchina da gioco, quindi la riduzione del server è una buona idea e assomiglia al modo in cui la descrivi.

Un'altra possibilità è scaricare il lavoro su un altro sistema di terze parti, ad es. altri client (già connessi): questo può essere fatto in modo sicuro se la funzione di hash include le strutture matematiche necessarie. Tale offloading è noto come delegazione . Per quanto ne so, la delega è offerta da una sola funzione di hashing della password, chiamata Makwa (vedi specifica ), uno dei candidati dell'attuale Concorso di hashing delle password .

    
risposta data 25.05.2014 - 21:20
fonte
1

Penso che la maggiore preoccupazione di questo approccio sia che sposta una procedura di sicurezza che è stata determinata importante dai tuoi server e ai browser web degli utenti. Mentre normalmente tutto dovrebbe funzionare come previsto, non hai un modo reale per verificare che la password sia stata effettivamente sottoposta a hash con bcrypt prima che ti venga inviata. Quindi, se il codice JavaScript sul lato client viene modificato, potresti comunque trovare solo un hash SHA256 di "123456" sul tuo server.

Certo, puoi controllare il formato dei dati inviati dal client per assicurarti che sia stato sottoposto a hash con bcrypt, ma non sai per certo che l'operazione desiderata sia stata completata.

Questo non è un modello di sicurezza ideale, ma nonostante ciò penso che le minacce a questo sistema siano ancora abbastanza gestibili. E tu saresti in vantaggio su quei siti che non hanno hash o hash con MD5 semplice.

    
risposta data 25.05.2014 - 21:23
fonte

Leggi altre domande sui tag