Diciamo che ho un sistema in cui uno dei requisiti di sicurezza è impedire agli utenti di scegliere una password che corrisponda al loro nome utente. I nomi utente non fanno distinzione tra maiuscole e minuscole, ma lo sono le password. Le password vengono memorizzate dal server utilizzando una funzione di hashing sicura che non può essere annullata.
Quando l'account viene creato, sia il nome utente che la password sono inizialmente disponibili in chiaro al server per il confronto. Possiamo confrontarli in memoria (ignorando le maiuscole e minuscole) per vedere se corrispondono e istruire l'utente a scegliere una password diversa se lo fanno. Una volta soddisfatto questo controllo, la password viene sottoposta a hashing in modo sicuro per l'archiviazione mentre il nome utente viene archiviato in testo normale. Nessun problema a soddisfare il requisito qui.
Quando l'utente vuole cambiare la propria password, o viene cambiata per lui, il server può recuperare il proprio nome utente e confrontarlo con il valore della password appena scelta (ignorando di nuovo case) per vedere se corrisponde. Nessun problema a soddisfare i requisiti anche qui.
Tuttavia, il sistema consente anche modifiche al nome utente. Durante questo processo di modifica dell'ID, l'utente non ha necessariamente fornito la propria password in chiaro al server. Potrebbero averlo fatto quando si sono autenticati, ma il server non manterrà la password archiviata in testo normale nel caso in cui decidessero di cambiare il loro nome utente. Quindi la password in testo normale non è disponibile per verificare una corrispondenza con il valore del nome utente appena scelto.
Nel tentativo di soddisfare i nostri requisiti, il server può utilizzare la stessa funzione di hashing sicuro per eseguire l'hash del nuovo nome utente e confrontarlo con la password con hash registrata. Se corrispondono, il server può chiedere all'utente di scegliere un nome utente diverso. Tuttavia, poiché il nome utente non fa distinzione tra maiuscole e minuscole, questo controllo potrebbe non riuscire quando è verosimilmente vero. Se invio "PwdRsch1" come nuova scelta di nome utente e la mia password è "pwdrsch1", il sistema lo consentirà poiché gli hash non corrispondono. Io, o peggio, un utente malintenzionato, potrei successivamente autenticarmi con successo con un nome utente e una password corrispondenti di "pwdrsch1".
Potremmo forzare il nome utente in minuscolo prima di eseguire l'hashing e confrontarlo con la password, ma allora è possibile lo scenario inverso. Il nome utente verrebbe verificato come "pwdrsch1" rispetto a una password di "PwdRsch1" e consentito poiché non corrispondono. Ma in seguito posso autenticarmi con successo con un nome utente e una password corrispondenti di "PwdRsch1".
Quali opzioni ragionevoli ho per ridurre questo rischio che una password corrisponda a un nome utente che non distingue tra maiuscole e minuscole?