Esiste uno svantaggio crittografico nell'applicare bcrypt a una password già hash

3

Inizialmente avevo chiesto questo su StackOverflow , ma a causa della mancanza di trazione e di una raccomandazione da parte di un utente, l'ho chiesto anche qui.

Immagina uno scenario in cui un'applicazione client invia una password a un server di back-end in modo che il server possa verificare che l'utente abbia inserito la password corretta quando viene confrontata con una variante memorizzata della password.

Il meccanismo di trasporto è HTTPS con il server che fornisce HSTS & HPKP per l'agente utente e potenti cifrari crittografici preferiti dal server che ha ottenuto un punteggio A + sul test dei laboratori SSL. Tuttavia, potremmo voler evitare di inviare la password originale fornita dall'utente al server dall'agente utente. Invece forse manderemmo un hash dopo un certo numero di round di SHA-256 sul client.

Sul lato server, per l'archiviazione delle password utilizziamo bcrypt con un numero elevato di round.

Da un punto di vista crittografico, c'è qualche svantaggio nell'esecuzione di bcrypt sul valore hash già sha-256 rispetto a direttamente sulla password di testo normale? La natura di lunghezza fissa del testo di input quando si utilizzano hash in qualche modo compromette i punti di forza dell'algoritmo.

Non sto chiedendo informazioni su prestazioni come memoria, CPU, requisiti di memoria o tempo di wall clock necessari per calcolare, memorizzare, inviare o confrontare valori. Sono semplicemente interessato a se applicare un hash prima dell'applicazione di bcrypt potrebbe indebolire la forza di bcrypt nel caso di una divulgazione dell'intero elenco di valori memorizzati.

Ho letto post questo (che trovo interessante e utile), ma non sto specificatamente chiedendo se è una buona idea di hash sul lato client - Sono più interessato a se fare quindi potrebbe in qualche modo indebolire il sistema di memorizzazione delle password con bcrypt dato che un utente malintenzionato armato di questa conoscenza saprebbe che tutti i valori memorizzati sono derivati da una lunghezza fissa di input costituita da un intervallo molto più piccolo di possibili caratteri (SHA-256)

    
posta David Goate 11.06.2018 - 10:55
fonte

2 risposte

3

Beh, in teoria, utilizzando esplicitamente le uscite SHA256 come input, limita la quantità di possibili input, ma l'enorme numero (!) di uscite SHA256 lo rende un fattore trascurabile. Sapere ciò non offre alcun vantaggio reale (per quanto ne sappiamo oggi), poiché l'output dell'hash è praticamente pseudo-casuale. Non ci dovrebbe essere molta differenza tra tutte le possibili uscite SHA256 e 2 256 stringhe casuali che vengono inserite nella funzione. Non è possibile derivare un pattern dagli output (se possibile, la funzione hash è errata). Non riesco a vedere le principali implicazioni da una prospettiva crittografica.

Un commento sul tuo scenario, o perché l'hashing sul lato client non è un miglioramento rispetto all'invio di testo semplice:

L'uso dell'hash sul lato client impedisce a un utente malintenzionato di ottenere una password di testo non crittografato, SE (enorme se, come hai descritto un sacco di standard di sicurezza elevati) possono comprendere la connessione SOMEWHERE. Tuttavia, eseguendo l'hashing della password prima di inviarlo, l'hash diventa effettivamente la nuova password, poiché al server non interessa se la password fornita è un hash o "topSecretK3y".

Se un utente malintenzionato ottiene questo hash, il suo valore è solo alto come la password originale, poiché ora può impersonare la vittima.

P.S .: L'unico "svantaggio" è che l'utente malintenzionato non può utilizzare il nome utente / password per altri siti Web, in modo da impedire almeno un "attacco di riutilizzo della password" su altri siti Web.

    
risposta data 11.06.2018 - 11:17
fonte
4

Finché il primo hash non è orribilmente rotto (e intendo spezzato così male che è significativamente peggio di MD5) questo non indebolisce l'hash bcrypt in alcun modo notevole. In effetti, l'esecuzione di un ciclo di SHA256 prima di bcrypt è effettivamente consigliata a volte perché bcrypt tronca silenziosamente a 72 caratteri. Mentre 72 caratteri dovrebbero essere più che sufficienti per una buona frase segreta, il troncamento silenzioso non è l'ideale.

Tuttavia , ci sono dettagli significativi sull'implementazione che devi essere a conoscenza se vuoi farlo. bcrypt è stato progettato per hash stringhe , non dati e, come tale, utilizza stringhe con terminazione nulla. Quello che in realtà vuoi fare è bcrypt(base64(sha256(password))) piuttosto che bcrypt(sha256(password)) , altrimenti un 0 byte vicino al fronte dell'hash sha256 sarebbe catastrofico, in quanto bcrypt avrebbe solo hash i primi caratteri.

Se il tuo obiettivo è quello di impedire a un MitM passivo di ottenere la password originale, allora fare sha256 lato client è utile, tuttavia non ti protegge tanto quanto pensi se la tua preoccupazione è una perdita di database. Aggiungere un sha256 prima di bcrypt in realtà non cambia nulla in termini di tempo necessario per decifrare le password, significa solo che l'autore dell'attacco deve eseguire le sue ipotesi anche attraverso sha256 , il che non li rallenta in calo rispetto all'utilizzo di un costo elevato per bcrypt .

    
risposta data 11.06.2018 - 16:58
fonte