È meglio hash n * volte x in sha1 o n volte in sha512 sul lato client?

6

So già che avrò hash la password dell'utente n volte in sha512 o n * x in sha1 prima che venga inviata al server. Una volta sul server, userò bcrypt set per usare ~ 1/100 di secondo Prima di andare avanti, seguendo il mio ragionamento sull'uso di sha512 invece di sha1, vorrei precisare alcune cose: in primo luogo, so che la sicurezza lato client è uno scherzo. un attacco Man-in-the-middle potrebbe spogliare il javascript della pagina della funzione hash. Infine, mi rendo conto che questo significherà che le persone non potranno accedere senza che javascript sia abilitato.

Attualmente sto usando il set sha512 per usare ~ 1s in ie8 [2], è configurato come tale.

  1. Utilizza la password e il nome utente dell'utente.
  2. Aggiungi un statico-nonce (per allungarlo davvero e nient'altro).
  3. Hash tramite la funzione di hashing, in questo caso sha512.
  4. Prendi quell'hash, esegui l'hash tramite sha512 con il numero del loop corrente racchiuso in un singolo byte.
  5. ripeti il passaggio 4 volte.
  6. Al termine, prendi quel valore e inseriscilo nel campo della password.
  7. consente infine al sistema di inviare POST al server.

Ora, qual è il vantaggio di fare n * x hash di sha1 rispetto ai n volte di sha512. L'intero punto dietro l'utilizzo di questo sistema è che, in caso di perdita di un database, l'utente malintenzionato dovrà aumentare la quantità di tempo trascorso cercando di trovare la password entro l'ora z. Inoltre, eseguendo l'hashing prima che raggiunga anche il server (insieme all'utilizzo di TLS), lo fa, in modo che, in caso di qualche strano bug, la password non venga mai vista come testo normale.

Credo che sha512 sia una scelta migliore dato che c'è già un'interruzione di sha1 e quindi la sicurezza non vale la pena, ma dall'altra parte. La libreria javascript più veloce che ho trovato per sha512 [1] [] è ~ 50 volte più lenta del codice nativo, ma la libreria sha1 più veloce che ho trovato è solo ~ 17 volte più lenta del codice nativo.

Quindi è una questione di come lo sha1 rotto possa causare una perdita maggiore nella sicurezza generale e quindi il rallentamento di un hacker piuttosto che fare meno iterazioni di sha512 che a tutt'oggi nessuno della famiglia di sha2 è in remoto. Qualcun altro ha già affrontato questo problema in precedenza?

[1]: che via fuzzing risulta nello stesso hash dell'implementazione c / php si ottiene lo stesso hash per ~ 300 input.

[2]: un anno dopo l'uscita di ie10, vorrei rilasciare il supporto per ie8 in modo da poter aumentare il numero di hash a qualcosa di più ragionevole.

    
posta 133794m3r 13.07.2011 - 00:47
fonte

2 risposte

9

Questo suona un po 'teso, forse controproducente, subottimale e in realtà non offre molta sicurezza aggiuntiva. La "password" è in realtà vista in chiaro, perché la password è la stringa che infine si invia al posto della password reale. Cosa stai cercando di ottenere esattamente?

In ogni caso, se stai davvero cercando di avere la "vera" password "non visibile in chiaro" (e non ti fidi di ssl) dovresti cercare di implementare un protocollo challenge-response. Questo è solitamente il modo in cui si procede se non vuole che la password sia trasportata in chiaro (o qualcosa che assomigli alla password come nel tuo caso).

Ora, se vuoi davvero continuare il tuo piano, e continuare a fare quel trucco sul lato del client che descrivi, SHA-1 va perfettamente bene per quello. Anche MD5 va bene e considerevolmente più veloce. Il "parlare per strada" di quelle funzioni che non sono sicure riguarda le collisioni - che probabilmente non ti interessa nella tua implementazione. Puoi anche dare un'occhiata al link , è una libreria jquery che esegue la crittografia asimmetrica dei moduli html.

Ma, di nuovo, sconsiglio vivamente a questa intera implementazione.

    
risposta data 13.07.2011 - 03:50
fonte
9

La protezione aggiuntiva aggiunta dall'hash del lato client è estremamente marginale. Dal punto di vista del server, il risultato hash è la password, poiché il server concede l'accesso a chiunque sia in grado di mostrare quel valore hash, senza richiedere la password effettiva. In particolare, se un "bizzarro bug" risulta nel rendere il valore hash apparente per l'aggressore, allora hai perso: l'attaccante può semplicemente connettersi al server mostrandogli il valore hash, senza eseguire il tuo javascript (gli utenti medi possono avere difficoltà a eludere un po 'di Javascript, ma non sarebbe sicuro presumere che l'attaccante non sia un po' più capace.

Ciò che rimane della protezione è che se l'hacker vede solo l'hash, non ha (ancora) indovinato la "vera password" e non sarà (immediatamente) in grado di provare quella password su altri server dove lo stesso utente ha anche un account. Questo non modifica nulla per la sicurezza del tuo server ma potrebbe essere visualizzato come un "servizio di community".

Per quanto riguarda il costo extra di attacco indotto dall'hashing multiplo: sebbene l'idea sia valida, l'uso di Javascript non lo è. Javascript è molto più lento di C o assembly. Ci vuole un secondo con IE8 in Javascript, ma nulla impone all'attaccante di eseguire il suo attacco in Javascript. Potrebbe usare C, assembly, possibilmente una GPU. Se vuoi rendere difficili gli attacchi con i dizionari, devi rendere l'hashing lento per l'attaccante . Effettuandolo sul client in Javascript, si impedisce di effettuare il numero di iterazioni necessario per ottenere una protezione adeguata. Un modo per vederlo è il seguente: vogliamo che ogni "ipotesi" sia lenta per l'aggressore. Sfortunatamente, non possiamo renderlo lento per l'attaccante a meno che non lo rendiamo lento anche per il "sistema onesto". Quindi le prestazioni dei sistemi onesti (client e / o server) limitano la quantità di lentezza che possiamo iniettare. Operando sul client in un linguaggio subottimale, rendiamo artificialmente la lentezza molto più pesante per i sistemi onesti e non per l'aggressore.

In pratica, il costo dell'attacco sarà quello di bcrypt; l'hashing sarà trascurabile in confronto. Ciò è particolarmente vero per SHA-512, che utilizza operazioni con numeri interi a 64 bit, che sono terribilmente lenti da implementare in Javascript, a causa della mancanza di tipi di numeri interi a 64 bit. Quindi la risposta precisa alla tua domanda è: usare SHA-1 (o SHA-256) sarebbe "migliore" di SHA-512 se l'obiettivo è quello di indurre la lentezza negli attacchi del dizionario; ma anche così, la lentezza indotta sarà trascurabile rispetto a ciò che fa bcrypt sul lato server, quindi la domanda è abbastanza priva di significato. D'altra parte, 1 ritardo in più farà infuriare i normali utenti, che sono noti per non avere pazienza.

    
risposta data 13.07.2011 - 14:19
fonte