Sto cercando di capire quale sarebbe il sistema di autenticazione "perfetto" per un sito web.
Da un lato, sappiamo che gli algoritmi di hashing semplici possono essere forzati o incrinati in altri modi. Quindi perché MD5 non è più raccomandato. La migliore soluzione per l'archiviazione sicura delle password, a quanto pare, si avvale di un allungamento delle chiavi in combinazione con la salatura (cioè utilizzando PBKDCF2, bcrypt o scrypt). Per coloro che non ne hanno sentito parlare, l'allungamento delle chiavi implica che un algoritmo di hash verrà calcolato attraverso molte iterazioni (non solo una volta), facendo sì che ogni tentativo di forza bruta prenda una quantità di tempo irragionevole per il calcolo.
Ora, se gli utenti si registrano, autenticano o modificano la loro password e il server utilizza la chiave che si estende per memorizzare la password, garantisce una protezione adeguata della password, ma lascia aperta la porta per gli attacchi DoS. Soprattutto, un hacker potrebbe invaderlo con tentativi di autenticazione con password casuali, e il server potrebbe soffocare sul calcolo di tutte quelle iterazioni per tutti quei tentativi.
Sto cercando di ottenere il meglio da entrambi i mondi: archiviazione sicura delle password con stretching chiave, senza la porta DoS aperta. Ecco la mia idea, e voglio sapere se sto supervisionando qualcosa, o se c'è qualche problema nella mia logica ... a volte, quando sei troppo vicino al problema ...
L'idea è:
-
CLIENT-SIDE: l'utente del sito web inserisce nome utente, password
-
CLIENT-SIDE: il sito Web utilizza la richiesta AJAX sul server per recuperare il numero di sale e il numero di iterazioni associate al record dell'utente (in base alla corrispondenza del nome utente)
-
CLIENT-SIDE: Autenticazione Passaggio 1. Il sito web calcola, sul computer client con Javascript, tutte le iterazioni di hashing MINUS ONE (spiegherò perché dopo). Il calcolo viene eseguito utilizzando un algoritmo ben noto, come PBKDF2, bcrypt o scrypt. Il sito Web invia il risultato al server.
-
SERVER-SIDE: Autenticazione Passaggio 2. Il server riceve lo username + la password hash (meno un'iterazione). Esegue l'ultima iterazione (con PBKDF2, bcrypt o scrypt) Confronta con il valore memorizzato per determinare se la combinazione è corretta. Restituisce la risposta al sito Web.
Ora, perché tutte le iterazioni meno uno? Se un hacker ottiene una copia del database e il server si aspetterebbe che venisse fornita una password completamente hash, sarebbe equivalente a memorizzare le password in testo normale. Hacker copia e incolla l'hash e usa il servizio di autenticazione. Pertanto, non possiamo restituirlo direttamente.
Tuttavia, poiché teoricamente non è possibile "invertire" l'hashing, se il server accetta solo un hash iterato n-1 significa che l'hacker non può indovinare quale sia l'iterazione precedente, in base a ciò che vediamo nel database. È corretto?
Alla fine, la maggior parte del lavoro viene eseguita sul lato client (il server esegue solo una iterazione), eliminando la minaccia DoS, ma abbiamo anche le password memorizzate con il key-stretching completo con salt, un pratica più sicura.
Mi manca qualcosa? Questo sarebbe un modo ideale per implementare un sistema di autenticazione? Fammi sapere! Mi sto solo chiedendo se mi manca qualcosa qui ...