Come hash una password

hey, mi piacerebbe memorizzare l’hash di una password sul telefono, ma non sono sicuro di come farlo. Posso solo sembrare di trovare metodi di crittografia. Qual è il modo migliore per cancellare la password? Grazie

AGGIORNAMENTO : QUESTA RISPOSTA E ‘SERIAMENTE AGGIORNATA . Si prega di utilizzare i consigli dal https://stackoverflow.com/a/10402129/251311 invece.

Puoi usare

var md5 = new MD5CryptoServiceProvider(); var md5data = md5.ComputeHash(data); 

o

 var sha1 = new SHA1CryptoServiceProvider(); var sha1data = sha1.ComputeHash(data); 

Per ottenere data come array di byte che è ansible utilizzare

 var data = Encoding.ASCII.GetBytes(password); 

e per recuperare la stringa da md5data o sha1data

 var hashedPassword = ASCIIEncoding.GetString(md5data); 

La maggior parte delle altre risposte qui sono alquanto obsolete con le migliori pratiche di oggi. Come tale ecco l’applicazione di utilizzare PBKDF2 / Rfc2898DeriveBytes per archiviare e verificare le password. Il seguente codice è in una class autonoma in questo post: Un altro esempio di come memorizzare un hash della password salata . Le basi sono davvero facili, quindi qui è ripartito:

PASSAGGIO 1 Creare il valore di sale con un PRNG crittografico:

 byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]); 

PASSAGGIO 2 Creare Rfc2898DeriveBytes e ottenere il valore hash:

 var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000); byte[] hash = pbkdf2.GetBytes(20); 

PASSO 3 Combina i byte salt e password per un uso successivo:

 byte[] hashBytes = new byte[36]; Array.Copy(salt, 0, hashBytes, 0, 16); Array.Copy(hash, 0, hashBytes, 16, 20); 

PASSAGGIO 4 Trasforma il sale combinato + l’hash in una stringa per la conservazione

 string savedPasswordHash = Convert.ToBase64String(hashBytes); DBContext.AddUser(new User { ..., Password = savedPasswordHash }); 

PASSAGGIO 5 Verificare la password immessa dall’utente rispetto a una password memorizzata

 /* Fetch the stored value */ string savedPasswordHash = DBContext.GetUser(u => u.UserName == user).Password; /* Extract the bytes */ byte[] hashBytes = Convert.FromBase64String(savedPasswordHash); /* Get the salt */ byte[] salt = new byte[16]; Array.Copy(hashBytes, 0, salt, 0, 16); /* Compute the hash on the password the user entered */ var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000); byte[] hash = pbkdf2.GetBytes(20); /* Compare the results */ for (int i=0; i < 20; i++) if (hashBytes[i+16] != hash[i]) throw new UnauthorizedAccessException(); 

Nota: in base ai requisiti di prestazione della specifica applicazione, è ansible ridurre il valore '10000'. Un valore minimo dovrebbe essere intorno a 1000.

Sulla base dell’ottima risposta di csharptest.net , ho scritto una class per questo:

 public sealed class SecurePasswordHasher { ///  /// Size of salt ///  private const int SaltSize = 16; ///  /// Size of hash ///  private const int HashSize = 20; ///  /// Creates a hash from a password ///  /// the password /// number of iterations /// the hash public static string Hash(string password, int iterations) { //create salt byte[] salt; new RNGCryptoServiceProvider().GetBytes(salt = new byte[SaltSize]); //create hash var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations); var hash = pbkdf2.GetBytes(HashSize); //combine salt and hash var hashBytes = new byte[SaltSize + HashSize]; Array.Copy(salt, 0, hashBytes, 0, SaltSize); Array.Copy(hash, 0, hashBytes, SaltSize, HashSize); //convert to base64 var base64Hash = Convert.ToBase64String(hashBytes); //format hash with extra information return string.Format("$MYHASH$V1${0}${1}", iterations, base64Hash); } ///  /// Creates a hash from a password with 10000 iterations ///  /// the password /// the hash public static string Hash(string password) { return Hash(password, 10000); } ///  /// Check if hash is supported ///  /// the hash /// is supported? public static bool IsHashSupported(string hashString) { return hashString.Contains("$MYHASH$V1$"); } ///  /// verify a password against a hash ///  /// the password /// the hash /// could be verified? public static bool Verify(string password, string hashedPassword) { //check hash if (!IsHashSupported(hashedPassword)) { throw new NotSupportedException("The hashtype is not supported"); } //extract iteration and Base64 string var splittedHashString = hashedPassword.Replace("$MYHASH$V1$", "").Split('$'); var iterations = int.Parse(splittedHashString[0]); var base64Hash = splittedHashString[1]; //get hashbytes var hashBytes = Convert.FromBase64String(base64Hash); //get salt var salt = new byte[SaltSize]; Array.Copy(hashBytes, 0, salt, 0, SaltSize); //create hash with given salt var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations); byte[] hash = pbkdf2.GetBytes(HashSize); //get result for (var i = 0; i < HashSize; i++) { if (hashBytes[i + SaltSize] != hash[i]) { return false; } } return true; } } 

Uso:

 //Hash var hash = SecurePasswordHasher.Hash("mypassword"); //Verify var result = SecurePasswordHasher.Verify("mypassword", hash); 

Un esempio di hash potrebbe essere questo:

 $MYHASH$V1$10000$Qhxzi6GNu/Lpy3iUqkeqR/J1hh8y/h5KPDjrv89KzfCVrubn 

Come puoi vedere, ho anche incluso le iterazioni nell'hash per un facile utilizzo e la possibilità di aggiornarlo, se è necessario eseguire l'aggiornamento.

Uso un hash e un sale per la crittografia della mia password (è lo stesso hash utilizzato da Asp.Net Membership):

 private string PasswordSalt { get { var rng = new RNGCryptoServiceProvider(); var buff = new byte[32]; rng.GetBytes(buff); return Convert.ToBase64String(buff); } } private string EncodePassword(string password, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(password); byte[] src = Encoding.Unicode.GetBytes(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inarray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inarray); }