Hash string w C #

91

Mam problem, gdy próbuję uzyskać ciąg skrótu c#.

Wypróbowałem już kilka witryn internetowych, ale większość z nich używa plików do uzyskania skrótu. Inne, które są przeznaczone na smyczki, są nieco zbyt złożone. Znalazłem przykłady uwierzytelniania systemu Windows dla stron internetowych, takie jak:

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

Muszę użyć skrótu, aby uczynić ciąg zawierający nazwę pliku bardziej bezpiecznym. Jak mogę to zrobić?

Przykład:

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

Czy powinienem użyć innego algorytmu mieszającego, a nie „md5”?

Edy Cu
źródło

Odpowiedzi:

183
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();
}

Dodatkowe uwagi

  • Ponieważ MD5 i SHA1 są przestarzałymi i niezabezpieczonymi algorytmami, to rozwiązanie wykorzystuje algorytm SHA256. Alternatywnie, można użyć BCrypt lub Scrypt jak wskazano w komentarzach.
  • Zastanów się również nad „ soleniem ” swoich skrótów i użyj sprawdzonych algorytmów kryptograficznych, jak wskazano w komentarzach.
Dmitry Polomoshnov
źródło
46
NIE UŻYWAJ MD5 ANI SHA1 , są to przestarzałe i niezabezpieczone algorytmy. Użyj co najmniej SHA256 lub nawet lepiej użyj BCrypt lub Scrypt.
Muhammad Rehan Saeed
1
Zobacz ten przykład użycia SCrypt: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed
6
@Muh Można go łatwo użyć do sum kontrolnych, ponieważ jest znacznie szybszy niż SHA512. Ale rzeczywiście, aby przechowywać hasła, nie jest to zalecane, co jest słuszne.
LuckyLikey
5
Co to b.ToString("X2")oznacza?
Bilal Fazlani
1
@BilalFazlani patrz stackoverflow.com/questions/20750062/…
Hezi
60

Najszybszym sposobem uzyskania skrótu do przechowywania haseł jest następujący kod:

    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);
        }
    }

Uwagi:

  • jeśli metoda jest często wywoływana, tworzenie shazmiennej powinno zostać refaktoryzowane na pole klasy;
  • wyjście jest przedstawiane jako zakodowany ciąg szesnastkowy;
andrew.fox
źródło
SHA1Managedklasa nie jest zbyt kosztowna. zużywa około 130 bajtów i inicjalizuje je do jakiejś statycznej wartości, ale to wszystko. więc w większości przypadków nie powinno być problemu z wydajnością.
Earth Engine
1
SHA1ManagedJest również IDisposablei dlatego wymaga, aby zawinąć jego użycie w usingblok.
Earth Engine
Celem Disposemetody jest wyczyszczenie bufora wewnętrznego. Niezastosowanie się do tego grozi atakiem pamięci.
Earth Engine
3
@MuhammadRehanSaeed, kiedy powiedziałem, że SHA1Managednie jest kosztowne, mam na myśli, że jego tworzenie nie jest. Ponadto algorytm haszujący nie jest konieczny kosztowny. To musi być (niezwykle) kosztowne tylko wtedy, gdy chcesz znaleźć kolizję.
Earth Engine
1
@King_Fisher - to niemożliwe! Hash to funkcja jednokierunkowa, informacje są tracone. Jeśli chcesz odszyfrować, musisz użyć metody szyfrowania bez haszowania. BTW, szyfrowanie haseł to zła praktyka.
andrew.fox
8

Naprawdę nie rozumiem całego zakresu twojego pytania, ale jeśli potrzebujesz tylko skrótu łańcucha, bardzo łatwo to uzyskać.

Po prostu użyj metody GetHashCode.

Lubię to:

string hash = username.GetHashCode();
Cyril Gupta
źródło
1
Tak, tego właśnie szukasz. Ale kod to duży błąd. Pokaż pisz jak int hash = "nazwa użytkownika" .GetHasCode ();
Edy Cu
3
Dlaczego nazwa użytkownika została umieszczona w podwójnych cudzysłowach? W ten sposób otrzymamy hash słowa „nazwa użytkownika” i zawartość zmiennej nazwy użytkownika.
Cyril Gupta
14
nie przechowuj wartości z GetHashCode, jest inaczej dla 32x i 64x
Slava
12
To zły sposób tworzenia skrótu hasła. Z GetHashCode () nie można zakładać, że ten sam numer zostanie wygenerowany na innym komputerze. Zastosowanie metody SHA1 hash lub coś (wyślę przykład później)
andrew.fox
2
Należy zauważyć, że GetHashCodenie jest to szyfrowany algorytm haszujący. Użyj co najmniej SHA256 lub nawet lepiej użyj BCrypt lub Scrypt dla bezpiecznego algorytmu.
Muhammad Rehan Saeed
5

Myślę, że to, czego szukasz, to nie haszowanie, ale szyfrowanie. Dzięki haszowaniu nie będziesz w stanie odzyskać oryginalnej nazwy pliku ze zmiennej „hash”. Dzięki szyfrowaniu możesz i jest to bezpieczne.

Zobacz AES w ASP.NET z VB.NET, aby uzyskać więcej informacji na temat szyfrowania w .NET.

Pieter van Ginkel
źródło
tak, myślę, że jest to szyfrowanie, ale chcę tylko porównać hash wyników. Po przekierowaniu strony.
Edy Cu
Z czym chcesz porównać zaszyfrowaną nazwę pliku?
Pieter van Ginkel
1
//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
źródło
3
NIE UŻYWAJ SHA1 z tego łącza, SHA1 to przestarzały i niezabezpieczony algorytm. Użyj co najmniej SHA256 lub nawet lepiej użyj BCrypt lub Scrypt.
Muhammad Rehan Saeed
Zobacz ten przykład użycia SCrypt: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed
1

Jeżeli wydajność nie jest głównym problemem, można również użyć jednej z następujących metod:
(W przypadku, gdy chciał ciąg mieszania się wielkimi literami, należy wymienić "x2"z "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")));
}

lub:

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
źródło
0

Najkrótsza i najszybsza droga w historii. Tylko 1 linia!

    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
źródło