Suppongo che il modo migliore di gestire le password per un sito Web sia creare un hash della password e salvare l'hash nel mio database. Quindi, quando qualcuno tenta di accedere, faccio un hash della password che hanno inserito e confronta.
È corretto?
E, c'è codice di esempio ovunque che mostra come farlo in C #?
E dovrei aggiungere un testo standard a ciascuna password in modo che il testo sottoposto a hash abbia sempre almeno 20 caratteri?
Aggiornamento: gli altri link non hanno il codice quindi ecco cosa ho implementato per questa domanda. Non includo il nome utente perché questo può cambiare, quindi solo salt: password. il: funziona perché uuencode non include:.
public static class EncryptionUtilities
{
private const int SALT_SIZE = 8;
private const int NUM_ITERATIONS = 1000;
private static readonly RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
/// <summary>
/// Creates a signature for a password.
/// </summary>
/// <param name="password">The password to hash.</param>
/// <returns>the "salt:hash" for the password.</returns>
public static string CreatePasswordSalt(string password)
{
byte[] buf = new byte[SALT_SIZE];
rng.GetBytes(buf);
string salt = Convert.ToBase64String(buf);
Rfc2898DeriveBytes deriver2898 = new Rfc2898DeriveBytes(password.Trim(), buf, NUM_ITERATIONS);
string hash = Convert.ToBase64String(deriver2898.GetBytes(16));
return salt + ':' + hash;
}
/// <summary>
/// Validate if a password will generate the passed in salt:hash.
/// </summary>
/// <param name="password">The password to validate.</param>
/// <param name="saltHash">The "salt:hash" this password should generate.</param>
/// <returns>true if we have a match.</returns>
public static bool IsPasswordValid(string password, string saltHash)
{
string[] parts = saltHash.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length != 2)
return false;
byte[] buf = Convert.FromBase64String(parts[0]);
Rfc2898DeriveBytes deriver2898 = new Rfc2898DeriveBytes(password.Trim(), buf, NUM_ITERATIONS);
string computedHash = Convert.ToBase64String(deriver2898.GetBytes(16));
return parts[1].Equals(computedHash);
}
}
ps - Ho considerato l'aggiunta di "The World Wonders" al testo hash perché è il sale più famoso di tutti i tempi. Tuttavia, ho pensato che non aggiungesse nulla e la crittografia non fosse il posto dove inserire le stringhe storiche.