Hash-String in c #

88

Ich habe ein Problem beim Versuch, eine Hash-Zeichenfolge einzugeben c#.

Ich habe bereits einige Websites ausprobiert, aber die meisten verwenden Dateien, um den Hash zu erhalten. Andere, die für Strings sind, sind etwas zu komplex. Ich habe Beispiele für die Windows-Authentifizierung für das Web wie folgt gefunden:

FormsAuthentication.HashPasswordForStoringInConfigFile(tbxPassword.Text.Trim(), "md5")

Ich muss einen Hash verwenden, um eine Zeichenfolge, die einen Dateinamen enthält, sicherer zu machen. Wie kann ich das machen?

Beispiel:

string file  = "username";
string hash = ??????(username); 

Sollte ich einen anderen Hashing-Algorithmus verwenden und nicht "md5"?

Edy Cu
quelle

Antworten:

180
using System.Security.Cryptography;

public static byte[] GetHash(string inputString)
{
    using (HashAlgorithm algorithm = SHA256.Create())
        return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}

public static string GetHashString(string inputString)
{
    StringBuilder sb = new StringBuilder();
    foreach (byte b in GetHash(inputString))
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}

Zusätzliche Bemerkungen

  • Da MD5 und SHA1 veraltete und unsichere Algorithmen sind, verwendet diese Lösung SHA256. Alternativ können Sie BCrypt oder Scrypt verwenden, wie in den Kommentaren angegeben.
  • Ziehen Sie auch in Betracht, Ihre Hashes zu " salzen " und bewährte kryptografische Algorithmen zu verwenden, wie in den Kommentaren ausgeführt.
Dmitry Polomoshnov
quelle
46
VERWENDEN SIE NICHT MD5 ODER SHA1 , es handelt sich um veraltete und unsichere Algorithmen. Verwenden Sie mindestens SHA256 oder noch besser BCrypt oder Scrypt.
Muhammad Rehan Saeed
1
Sehen Sie dieses Beispiel der Verwendung von SCrypt: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed
6
@Muh Es kann leicht für Prüfsummen verwendet werden, da es viel schneller als SHA512 ist. In der Tat wird das Speichern von Passwörtern nicht empfohlen, was richtig ist.
LuckyLikey
5
Was bedeutet das b.ToString("X2")?
Bilal Fazlani
2
Wenn Sie es nicht mit einer Regierungsbehörde oder einer Hacking-Gruppe zu tun haben, glaube ich, dass sogar md5 in Ordnung ist (es sei denn, es handelt sich um eine 1-Wort-Zeichenfolge aus einem Wörterbuch). Tolles Beispiel. Vielen Dank.
Nikos
59

Der schnellste Weg, um eine Hash-Zeichenfolge für Kennwortspeicherzwecke zu erhalten, ist ein folgender Code:

    internal static string GetStringSha256Hash(string text)
    {
        if (String.IsNullOrEmpty(text))
            return String.Empty;

        using (var sha = new System.Security.Cryptography.SHA256Managed())
        {
            byte[] textData = System.Text.Encoding.UTF8.GetBytes(text);
            byte[] hash = sha.ComputeHash(textData);
            return BitConverter.ToString(hash).Replace("-", String.Empty);
        }
    }

Bemerkungen:

  • Wenn die Methode häufig aufgerufen wird, sollte die Erstellung einer shaVariablen in ein Klassenfeld umgestaltet werden.
  • Die Ausgabe wird als codierte Hex-Zeichenfolge dargestellt.
andrew.fox
quelle
SHA1ManagedKlasse ist nicht sehr teuer. Es verbraucht ungefähr 130 Bytes und initialisiert sie auf einen statischen Wert, aber das ist alles. Daher sollte es in den meisten Fällen kein Leistungsproblem geben.
Earth Engine
Auch SHA1Managedist IDisposableund muss seine Verwendung in einen usingBlock einwickeln .
Earth Engine
Die Zweckmethode Disposebesteht darin, den internen Puffer zu löschen. Andernfalls besteht die Gefahr eines Speicherangriffs.
Earth Engine
3
@ MuhammadRehanSaeed, als ich sagte, SHA1Managedist nicht teuer, ich meine, seine Erstellung ist nicht. Auch ein Hashing-Algorithmus ist nicht teuer. Es muss nur (extrem) teuer sein, wenn Sie eine Kollision finden möchten.
Erdmotor
1
@King_Fisher - es ist unmöglich! Hash ist eine Einwegfunktion, Informationen gehen verloren. Wenn Sie entschlüsseln müssen, müssen Sie die Verschlüsselungsmethode ohne Hashing verwenden. Übrigens ist das Verschlüsseln von Passwörtern eine schlechte Praxis.
andrew.fox
7

Ich verstehe den vollen Umfang Ihrer Frage nicht wirklich, aber wenn Sie nur einen Hash der Zeichenfolge benötigen, ist es sehr einfach, diesen zu erhalten.

Verwenden Sie einfach die GetHashCode-Methode.

So was:

string hash = username.GetHashCode();
Cyril Gupta
quelle
1
Ja, dass es was sucht. Aber der Code ist ein großer Fehler. Show write like int hash = "Benutzername" .GetHasCode ();
Edy Cu
3
Warum haben Sie den Benutzernamen in doppelte Anführungszeichen gesetzt? Dadurch wird der Hash des Wortes "Benutzername" und nun, was in der Variablen "Benutzername" enthalten ist, angezeigt.
Cyril Gupta
14
Speichern Sie keine Werte von GetHashCode, es ist anders für 32x und 64x
Slava
12
Dies ist ein schlechter Weg, um einen Passwort-Hash zu erstellen. Mit GetHashCode () können Sie nicht davon ausgehen, dass dieselbe Nummer von einem anderen Computer generiert wird. Verwenden Sie die Sha1-Hash-Methode oder etwas anderes (ich werde später ein Beispiel veröffentlichen)
andrew.fox
2
Es ist zu beachten, dass dies GetHashCodekein kryptografisch sicherer Hashing-Algorithmus ist. Verwenden Sie mindestens SHA256 oder noch besser BCrypt oder Scrypt für einen sicheren Algorithmus.
Muhammad Rehan Saeed
5

Ich denke, was Sie suchen, ist nicht Hashing, sondern Verschlüsselung. Mit Hashing können Sie den ursprünglichen Dateinamen nicht aus der Variablen "Hash" abrufen. Mit Verschlüsselung können Sie, und es ist sicher.

Weitere Informationen zur Verschlüsselung in .NET finden Sie unter AES in ASP.NET mit VB.NET .

Pieter van Ginkel
quelle
Ja, ich denke, es ist Verschlüsselung, aber ich möchte nur den Ergebnis-Hash vergleichen. Nach der Weiterleitung der Seite.
Edy Cu
Womit möchten Sie den Hash-Dateinamen vergleichen?
Pieter van Ginkel
2
//Secure & Encrypte Data
    public static string HashSHA1(string value)
    {
        var sha1 = SHA1.Create();
        var inputBytes = Encoding.ASCII.GetBytes(value);
        var hash = sha1.ComputeHash(inputBytes);
        var sb = new StringBuilder();
        for (var i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }
Soufiane Neffar
quelle
3
VERWENDEN SIE SHA1 NICHT über diesen Link. SHA1 ist ein veralteter und unsicherer Algorithmus. Verwenden Sie mindestens SHA256 oder noch besser BCrypt oder Scrypt.
Muhammad Rehan Saeed
Sehen Sie dieses Beispiel der Verwendung von SCrypt: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed
1

Wenn die Leistung kein großes Problem darstellt, können Sie auch eine der folgenden Methoden verwenden:
( Wenn Sie möchten, dass die Hash-Zeichenfolge in Großbuchstaben geschrieben wird, ersetzen Sie sie "x2"durch "X2".)

public static string SHA256ToString(string s) 
{
    using (var alg = SHA256.Create())
        return string.Join(null, alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Select(x => x.ToString("x2")));
}

oder:

public static string SHA256ToString(string s)
{            
    using (var alg = SHA256.Create())
        return alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Aggregate(new StringBuilder(), (sb, x) => sb.Append(x.ToString("x2"))).ToString();
}
Babak
quelle
0

Der kürzeste und schnellste Weg aller Zeiten. Nur 1 Zeile!

    public static string StringSha256Hash(string text) =>
        string.IsNullOrEmpty(text) ? string.Empty : BitConverter.ToString(new System.Security.Cryptography.SHA256Managed().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text))).Replace("-", string.Empty);
Erçin Dedeoğlu
quelle