web-dev-qa-db-fra.com

Hacher une corde avec Sha256

J'essaie de hacher une chaîne en utilisant SHA256, j'utilise le code suivant:

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

Cependant, ce code donne des résultats très différents de ceux de mes amis php, ainsi que des générateurs en ligne (tels que Ce générateur )

Est-ce que quelqu'un sait quelle est l'erreur? Différentes bases?

133
Nattfrosten

Encoding.Unicode est le nom trompeur de Microsoft pour UTF-16 (codage double largeur, utilisé dans le monde Windows pour des raisons historiques mais non utilisé par quiconque). http://msdn.Microsoft.com/en-us/library/system.text.encoding.unicode.aspx

Si vous inspectez votre tableau bytes, vous verrez que chaque octet de seconde est 0x00 (en raison du codage à double largeur).

Vous devriez utiliser Encoding.UTF8.GetBytes à la place.

Toutefois, vous obtiendrez des résultats différents selon que vous considérerez ou non l'octet de terminaison '\0' comme faisant partie des données que vous hachez. Le hachage des deux octets "Hi" donnera un résultat différent du hachage des trois octets "Hi". Vous devrez décider ce que vous voulez faire. (Vraisemblablement, vous voulez utiliser le code PHP de votre ami).)

Pour ASCII texte, Encoding.UTF8 conviendra certainement. Si vous visez une compatibilité parfaite avec le code de votre ami, même sur des entrées non-ASCII, vous feriez mieux d'essayer quelques cas de test avec Caractères ASCII tels que é et et voyez si vos résultats correspondent toujours. Sinon, vous devrez déterminer quel encodage votre ami utilise réellement; il s’agit peut-être d’une des "pages de code" à 8 bits qui étaient populaires avant l’invention de l’Unicode. (Encore une fois, je pense que Windows est la principale raison pour laquelle quiconque doit encore s'inquiéter des "pages de code".)

148
Quuxplusone

J'ai également eu ce problème avec un autre style de mise en œuvre, mais j'ai oublié où je l'ai eu depuis il y a 2 ans.

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

Lorsque je saisis quelque chose comme abcdefghi2013 pour une raison quelconque, les résultats sont différents et des erreurs se produisent dans mon module de connexion. Ensuite, j'ai essayé de modifier le code de la même manière que suggéré par Quuxplusone et de changer l'encodage de ASCII à UTF8, puis cela a finalement fonctionné!

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

Merci encore à Quuxplusone pour cette réponse merveilleuse et détaillée!:)

96
Nico Dumdum

Dans la version PHP, vous pouvez envoyer "true" dans le dernier paramètre, mais la valeur par défaut est "false". L'algorithme suivant est équivalent à la fonction de hachage de PHP par défaut lors du passage du paramètre 'sha256' comme premier paramètre:

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;
    }
4
Rachel