Memorizzare password in chiaro nel database è uno degli errori da evitare, se vogliamo salvaguardare la sicurezza degli account dei nostri utenti.
Una condotta più indicata è quella di salvare invece un hash della password, ovvero una sua impronta formata da una sequenza di caratteri non invertibile.
In ASP.NET Identity, il calcolo dell'hash viene affidato dalla classe PasswordHasher, che troviamo nel package NuGet Microsoft.AspNet.Identity.Core.
Le precise responsabilità di questo componente sono:
- Calcolare l'hash della password impostata dall'utente;
- Verificare che l'hash della password fornita durante il login corrisponda a quello salvato in precedenza.
Il PasswordHasher si avvale dell'algoritmo RFC 2898 (https://www.ietf.org/rfc/rfc2898.txt") per produrre un hash robusto, che scoraggia i tentativi di attacco finalizzati al recupero della password con brute force (http://it.wikipedia.org/wiki/Metodo_forza_bruta) o tramite le cosiddette rainbow table (http://it.wikipedia.org/wiki/Tabella_arcobaleno).
A volte, dobbiamo rinunciare a questo grado di robustezza in favore di un password hasher personalizzato. Se vogliamo per esempio iniziare ad usare ASP.NET Identity con un database preesistente, già popolato di utenti, allora dovremo adottare lo stesso algoritmo usato originariamente per produrre gli hash.
In questo esempio, scriviamo un semplice password hasher che si avvale dall'algoritmo SHA1.
Iniziamo aggiungendo una nuova classe SHA1PasswordHasher ad una cartella del nostro progetto, come ad esempio /Models, e facciamole implementare l'interfaccia IPasswordHasher.
public class SHA1PasswordHasher : IPasswordHasher { //L'hash viene prodotto qui, durante la registrazione o il cambio password public string HashPassword(string password) { if (password.Equals(null)) throw new ArgumentNullException("Devi fornire una password"); //Calcoliamo l'hash con la classe SHA1Managed var hasher = new SHA1Managed(); var buffer = Encoding.UTF8.GetBytes(password); var hash = hasher.ComputeHash(buffer); return BitConverter.ToString(hash).Replace("-", string.Empty); } //Il metodo di verfica viene invocato durante il login public PasswordVerificationResult VerifyHashedPassword(string hashedPassword, string providedPassword) { //Calcolo l'hash per la password immessa dall'utente durante il login var passwordHash = HashPassword(providedPassword); //Lo confronto con l'hash calcolato in precedenza var hashesMatch = hashedPassword.Equals(passwordHash, StringComparison.InvariantCultureIgnoreCase); return hashesMatch ? PasswordVerificationResult.Success : PasswordVerificationResult.Failed; } }
Ora non resta che creare un'istanza del nostro SHA1PasswordHasher ed assegnarla allo UserManager affinché ne faccia uso. Da una tipica applicazione ASP.NET MVC 5 creata con Visual Studio 2013, apriamo il file App_Start/IdentityConfig.cs e aggiungiamo la seguente riga nel metodo Create.
manager.PasswordHasher = new SHA1PasswordHasher();
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare la versione generica di EntityTypeConfiguration in Entity Framework Core
Creazione di plugin per Tailwind CSS: espandere le funzionalità del framework dinamicamente
Migliorare l'organizzazione delle risorse con Azure Policy
Modificare i metadati nell'head dell'HTML di una Blazor Web App
Usare i servizi di Azure OpenAI e ChatGPT in ASP.NET Core con Semantic Kernel
Utilizzare il trigger SQL con le Azure Function
Testare l'invio dei messaggi con Event Hubs Data Explorer
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Sostituire la GitHub Action di login su private registry
Utilizzare il nuovo modello GPT-4o con Azure OpenAI
C# 12: Cosa c'è di nuovo e interessante
Generare token per autenicarsi sulle API di GitHub