Hashing a string with Sha256

Próbuję hashować łańcuch używając SHA256, używam następującego kodu:

using System;
using System.Security.Cryptography;
using System.Text;
 public class Hash
    {
    public static string getHashSha256(string text)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        foreach (byte x in hash)
        {
            hashString += String.Format("{0:x2}", x);
        }
        return hashString;
    }
}

Jednak ten kod daje znacznie Inne wyniki w porównaniu do moich znajomych php, a także generatorów online (takich jak ten generator)

Czy ktoś wie co to jest błąd? Różne bazy?

Author: iliketocode, 2012-09-14

3 answers

Encoding.Unicode to myląca Nazwa UTF-16 (kodowania dwuznakowego, używanego w świecie Windows ze względów historycznych, ale nie używanego przez nikogo innego). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx

Jeśli sprawdzisz swoją tablicę bytes, zobaczysz, że co drugi bajt to 0x00 (ze względu na kodowanie dwuznakowe).

Zamiast tego powinieneś używać Encoding.UTF8.GetBytes.

Ale również, zobaczysz różne wyniki w zależności od tego, czy lub nie uważasz, że kończący '\0' bajt jest częścią danych, które zaszyfrowujesz. Hashowanie dwóch bajtów "Hi" da inny wynik od hashowania trzech bajtów "Hi". Musisz zdecydować, co chcesz zrobić. (Prawdopodobnie chcesz zrobić to, co robi kod PHP twojego przyjaciela.)

Dla tekstu ASCII, Encoding.UTF8 na pewno będzie odpowiedni. Jeśli dążysz do idealnej kompatybilności z kodem znajomego, nawet na wejściach innych niż ASCII, lepiej spróbuj kilka przypadków testowych ze znakami spoza ASCII, takimi jak é i i sprawdź, czy Twoje wyniki nadal się zgadzają. Jeśli nie, będziesz musiał dowiedzieć się, jakiego kodowania naprawdę używa Twój znajomy; może to być jedna z 8-bitowych "stron kodowych", które były popularne przed wynalezieniem Unicode. (Ponownie myślę, że Windows jest głównym powodem, dla którego ktoś nadal musi martwić się o "strony kodowe".)

 134
Author: Quuxplusone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-14 01:27:43

Miałem też ten problem z innym stylem implementacji, ale zapomniałem, skąd go mam, bo to było 2 lata temu.

static string sha256(string randomString)
{
    var crypt = new SHA256Managed();
    string hash = String.Empty;
    byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString));
    foreach (byte theByte in crypto)
    {
        hash += theByte.ToString("x2");
    }
    return hash;
}

Kiedy wprowadzam coś w rodzaju abcdefghi2013 z jakiegoś powodu daje to różne wyniki i powoduje błędy w module logowania. Potem próbowałem zmodyfikować kod w ten sam sposób, co sugerował Quuxplusone i zmieniłem kodowanie z ASCII na UTF8 i w końcu zadziałało!

static string sha256(string randomString)
{
    var crypt = new System.Security.Cryptography.SHA256Managed();
    var hash = new System.Text.StringBuilder();
    byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
    foreach (byte theByte in crypto)
    {
        hash.Append(theByte.ToString("x2"));
    }
    return hash.ToString();
}

Jeszcze raz dziękuję Quuxplusone za wspaniałą i szczegółową odpowiedź! :)

 80
Author: Nico Dumdum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 09:51:04

W wersji PHP możesz wysłać 'true' w ostatnim parametrze, ale domyślnym jest 'false'. Poniższy algorytm jest odpowiednikiem domyślnej funkcji skrótu PHP, gdy przekazuje 'sha256' jako pierwszy parametr:

public static string GetSha256FromString(string strData)
    {
        var message = Encoding.ASCII.GetBytes(strData);
        SHA256Managed hashString = new SHA256Managed();
        string hex = "";

        var hashValue = hashString.ComputeHash(message);
        foreach (byte x in hashValue)
        {
            hex += String.Format("{0:x2}", x);
        }
        return hex;
    }
 2
Author: Rachel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 11:07:38