it-swarm.com.de

Wie man ein Passwort hasht

hey, ich möchte den Hash eines Passworts auf dem Telefon speichern, bin mir aber nicht sicher, wie ich das machen soll. Ich kann anscheinend nur Verschlüsselungsmethoden finden. Was ist der beste Weg, um das Passwort zu hacken? Vielen Dank

106
Skoder

[~ # ~] Update [~ # ~] : DIESE ANTWORT IS = ERNST VERLAUFEN . Verwenden Sie stattdessen die Empfehlungen aus https://stackoverflow.com/a/10402129/251311 .

Sie können entweder verwenden

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

oder

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

Um data als Byte-Array zu erhalten, können Sie verwenden

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

und um einen String von md5data oder sha1data

var hashedPassword = ASCIIEncoding.GetString(md5data);
54
zerkms

Die meisten anderen Antworten hier sind mit den heutigen Best Practices etwas veraltet. Als solches ist hier die Anwendung der Verwendung von PBKDF2/Rfc2898DeriveBytes zum Speichern und Überprüfen von Passwörtern. Der folgende Code befindet sich in einer eigenständigen Klasse in diesem Beitrag: Ein weiteres Beispiel zum Speichern eines gesalzenen Kennwort-Hash . Die Grundlagen sind wirklich einfach, hier ist es aufgeschlüsselt:

SCHRITT 1 Erstellen Sie den Salzwert mit einem kryptografischen PRNG:

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

SCHRITT 2 Erstellen Sie den Rfc2898DeriveBytes und erhalten Sie den Hash-Wert:

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

SCHRITT 3 Kombinieren Sie die Salt- und Passwort-Bytes für die spätere Verwendung:

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

SCHRITT 4 Verwandeln Sie den kombinierten Salz + Hasch in einen String zur Aufbewahrung

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

SCHRITT 5 Überprüfen Sie das vom Benutzer eingegebene Passwort anhand eines gespeicherten Passworts

/* 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();

Hinweis: Abhängig von den Leistungsanforderungen Ihrer spezifischen Anwendung kann der Wert "10000" reduziert werden. Ein Mindestwert sollte bei 1000 liegen.

259
csharptest.net

Basierend auf csharptest.net's toller Antwort habe ich eine Klasse dafür geschrieben:

public static class SecurePasswordHasher
{
    /// <summary>
    /// Size of salt.
    /// </summary>
    private const int SaltSize = 16;

    /// <summary>
    /// Size of hash.
    /// </summary>
    private const int HashSize = 20;

    /// <summary>
    /// Creates a hash from a password.
    /// </summary>
    /// <param name="password">The password.</param>
    /// <param name="iterations">Number of iterations.</param>
    /// <returns>The hash.</returns>
    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);
    }

    /// <summary>
    /// Creates a hash from a password with 10000 iterations
    /// </summary>
    /// <param name="password">The password.</param>
    /// <returns>The hash.</returns>
    public static string Hash(string password)
    {
        return Hash(password, 10000);
    }

    /// <summary>
    /// Checks if hash is supported.
    /// </summary>
    /// <param name="hashString">The hash.</param>
    /// <returns>Is supported?</returns>
    public static bool IsHashSupported(string hashString)
    {
        return hashString.Contains("$MYHASH$V1$");
    }

    /// <summary>
    /// Verifies a password against a hash.
    /// </summary>
    /// <param name="password">The password.</param>
    /// <param name="hashedPassword">The hash.</param>
    /// <returns>Could be verified?</returns>
    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 hash bytes
        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;
    }
}

Verwendung:

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

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

Ein Beispiel-Hash könnte sein:

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

Wie Sie sehen, habe ich auch die Iterationen in den Hash für die einfache Verwendung und die Möglichkeit, diese zu aktualisieren, wenn wir aktualisieren müssen, aufgenommen.


Wenn Sie an .net Core interessiert sind, habe ich auch eine .net Core-Version auf Code Review .

58

Ich verwende einen Hash und ein Salt für meine Passwortverschlüsselung (es ist derselbe Hash, den Asp.Net Membership verwendet):

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);
}
13
Martin
  1. Kreiere ein Salz,
  2. Erstellen Sie ein Hash-Passwort mit Salt
  3. Bewahren Sie sowohl Haschisch als auch Salz auf
  4. mit Passwort und Salt entschlüsseln ... Entwickler können Passwort nicht entschlüsseln
public class CryptographyProcessor
{
    public string CreateSalt(int size)
    {
        //Generate a cryptographic random number.
          RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
         byte[] buff = new byte[size];
         rng.GetBytes(buff);
         return Convert.ToBase64String(buff);
    }


      public string GenerateHash(string input, string salt)
      { 
         byte[] bytes = Encoding.UTF8.GetBytes(input + salt);
         SHA256Managed sHA256ManagedString = new SHA256Managed();
         byte[] hash = sHA256ManagedString.ComputeHash(bytes);
         return Convert.ToBase64String(hash);
      }

      public bool AreEqual(string plainTextInput, string hashedInput, string salt)
      {
           string newHashedPin = GenerateHash(plainTextInput, salt);
           return newHashedPin.Equals(hashedInput); 
      }
 }
0
Bamidele Alegbe