Sfida impegnativa: hashing della password sul lato client e verifica della password sul lato server

13

Abbiamo un sito web in cui gli utenti devono accedere per accedere alle informazioni privilegiate. Ovviamente stiamo usando SSL, ma voglio anche evitare che le password in chiaro finiscano accidentalmente nei log del server, o gli occhi vagabondi degli amministratori. Pertanto, voglio implementare l'hashing lato client usando Javascript.

Inoltre, voglio evitare di rivelare coppie di utenti con password identiche, quindi utilizzare un sale specifico per utente. Infine, vorrei aggiungere una sfida casuale (alias nonce) nel mix per assicurarmi che un intercettatore * non possa usare l'hash finale come la nuova "password". Farò un roundtrip aggiuntivo al server web per ottenere il sale e la sfida prima di iniziare l'hashing della password. *) Sì, stiamo usando SSL, ma come difesa approfondita mi piacerebbe rendere l'implementazione più solida possibile.

Soprattutto la sfida è impegnativa. L'unica implementazione possibile che conosco è la prima volta che si calcola l'hash della password finale (usando bcrypt, scrypt o PBKDF2) e poi si esegue un ulteriore sha256_hmac round usando la sfida. Sul lato server recuperiamo l'hash della password dal database ed eseguiamo lo stesso sha256_hmac aggiuntivo e confrontiamo il risultato.

Tuttavia, quanto sopra implicherebbe che il calcolo dell'hash della password full deve essere eseguito lato client in Javascript, perché l'hashing nella sfida dovrebbe sempre essere l'ultimo passaggio. Su un iPhone legacy (?), Solo 6 round di crittografia o 5000 round di PBKDF2-SHA256 possono essere eseguiti entro 2 secondi, il massimo ritardo che possiamo tollerare.

Domanda n. 1: sono sicuro che oggigiorno bcrypt dovrebbe essere almeno 12 round e PBKDF2-SHA256 almeno 5000 round? Quindi dovrei scegliere i 5000 round di PBKDF2-SHA256?

Domanda n. 2: Esistono meccanismi di risposta alle sfide che possono operare prima nel processo (ad esempio su una password con hash una volta), quindi posso lasciare il bcrypt / PBKDF2 hardening al server web?

Domanda n. 3: supponendo che non esista un tale meccanismo di risposta alle sfide, è meglio abbandonare il mio requisito di risposta alla sfida e applicare solo un client salino specifico per utente e fare il lato completo del server di protezione? Ciò comporterebbe un sistema complessivo più strong rispetto all'utilizzo di un meccanismo di risposta alle sfide e meno round?

EDIT: riepilogare la lunga serie di commenti che seguono sulla sicurezza dell'hashing lato client in generale: l'opinione generale sembra essere che la complessità aggiunta non ne vale la pena ed è meglio mettere lo sforzo nel controllo del server codice a lato e limitazione dell'accesso lato server per il personale non autorizzato.

    
posta Jason Smith 12.07.2012 - 15:28
fonte

4 risposte

11

Penso che stai sprecando il tuo tempo e aggiungendo complessità inutile. Non penso che i motivi che fornisci siano sufficienti a giustificare questo tipo di meccanismo di hashing della password lato client.

Invece, suggerisco di mantenerlo semplice. Invia la password tramite un collegamento crittografato con SSL. Quando si tratta di sicurezza, semplice è buono. La complessità inutile è il nemico della sicurezza, perché introduce l'opportunità di errori e bug.

Risparmia energia per altre attività di sicurezza che affronteranno minacce più realistiche. C'è una quantità limitata di tempo, energia e budget che si possono spendere per migliorare la sicurezza; meglio spenderlo nei luoghi che produrranno il più grande successo per il dollaro (il più grande miglioramento della sicurezza, dato l'investimento). Penso che scoprirai che ci sono altri modi in cui potresti migliorare il tuo sistema per migliorare la sicurezza.

Se sei preoccupato che il codice lato server stia gestendo la password in modo appropriato, rivedi questo codice attentamente: dovrebbe essere contenuto in una porzione molto piccola di codice. Questo dovrebbe prendere in considerazione rischi come, ad esempio, il server che registra le password in chiaro: basta leggere ogni riga di codice che è coinvolta con il controllo della password o che legge la password, assicurarsi che la prima cosa che fa sia quella di hash la password in modo appropriato, e fare certo che tutto ciò che fa è controllare la validità della password e restituire vero o falso. Se il tuo sistema è ben progettato, questo dovrebbe essere abbastanza semplice da verificare attraverso la revisione del codice. Se il codice non è ben progettato, forse sarebbe il momento giusto per risolverlo.

    
risposta data 16.07.2012 - 01:06
fonte
6

Se non lo hai già fatto, potresti voler esaminare l'SRP. Dovrebbe soddisfare tutti i tuoi requisiti, se vuoi un sistema di tipo sfida / risposta.

link

    
risposta data 12.07.2012 - 22:16
fonte
4

Sarei diffidente nei confronti di qualsiasi protocollo preparato in casa. Sarei anche diffidente nei confronti di qualsiasi protocollo di autenticazione basato sull'hashing lato client. La soluzione migliore è studiare Autenticazione NTLM e il GRANDE NUMERO di attacchi contro questo protocollo. Come la vulnerabilità nonce debole NTLM .

(SRP non è male, SRP-TLS sembra piuttosto interessante.)

    
risposta data 14.07.2012 - 22:07
fonte
1
  1. No, sei ancora troppo piccolo. OWASP Password Storage Cheat Sheet raccomanda 64.000 iterazioni PBKDF2 nel 2012 e raddoppia ogni 2 anni (https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet).

  2. Vedi le altre risposte sopra.

  3. Hai la possibilità di fare un po 'di hashing sul lato client (per esempio, 2000 round di PBKDF2_SHA-1), e una volta che il risultato è arrivato al server, eseguilo attraverso un altro set di hashing (ad esempio , 300.000 round di PBKDF2_SHA-512) e confronta tale valore finale.

Il tuo database memorizza solo il valore double-PBKDF2 finale.

I tuoi file di log web e / o le tue sessioni SSL potenzialmente utilizza il valore intermedio single-PBKDF2. Mentre il valore intermedio è sicuramente molto, molto più debole del valore finale, è ancora molto più strong del testo trasparente.

Nota che devi anche controllare le password che gli utenti propongono quando si cambia la password / selezionare una nuova password con un normale dizionario cracking con alcune regole (minuscole sia per eliminare i giochi di casi, aggiungere numeri da 1 a 1000 dopo la parola, aggiungere date dopo una parola, 1337 di base pronuncia le traduzioni, ecc.) per impedire che la password "strong" "P @ $$ w0rd" (maiuscolo, minuscolo, simboli e numeri - 8 caratteri, deve essere davvero strong!) da presentandosi.

    
risposta data 02.11.2012 - 20:50
fonte

Leggi altre domande sui tag