168 votes

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?

171voto

Quuxplusone Points 4320

Encoding.Unicode Microsoft, qui est le nom trompeur pour UTF-16 (une double échelle de l'encodage, utilisé dans le monde de Windows pour des raisons historiques, mais pas utilisé par quelqu'un d'autre). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx

Si vous inspectez votre bytes tableau, vous verrez que chaque deuxième octet est - 0x00 (en raison de la double échelle de l'encodage).

Vous devriez être en utilisant Encoding.UTF8.GetBytes à la place.

Mais aussi, vous verrez des résultats différents selon que vous considérez ou non la résiliation '\0' octets à une partie des données, vous êtes de hachage. Le hachage les deux octets "Hi" donnera un résultat différent de hachage les trois octets "Hi". Vous aurez à décider qui vous voulez faire. (Je présume que vous voulez faire, celui de votre ami code PHP est en train de faire.)

Pour de texte ASCII, Encoding.UTF8 sera certainement approprié. Si vous visez pour parfaite compatibilité avec vos amis le code, même sur la non-ASCII entrées, vous feriez mieux d'essayer quelques-uns des cas de test avec des caractères non-ASCII comme é et et voir si vos résultats toujours à la hauteur. Si non, vous aurez à comprendre ce que le codage de votre ami est vraiment à l'aide; il pourrait être l'un de la 8-bits de code "pages" que l'habitude d'être populaire avant l'invention de l'Unicode. (Encore une fois, je pense que Windows est la principale raison pour laquelle quelqu'un a encore besoin de s'inquiéter à propos de "pages de code.)

124voto

Nico Dumdum Points 165

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

static string sha256(string password)
    {
        SHA256Managed crypt = new SHA256Managed();
        string hash = String.Empty;
        byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(password), 0, Encoding.ASCII.GetByteCount(password));
        foreach (byte bit in crypto)
        {
            hash += bit.ToString("x2");
        }
        return hash;
    }

Lorsque je saisie quelque chose comme "abcdefghi2013" pour une raison quelconque, il donne des résultats différents et les résultats dans les erreurs 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 changé l'encodage de l'ASCII vers UTF8 puis elle a finalement travaillé!

static string sha256(string password)
    {
        SHA256Managed crypt = new SHA256Managed();
        string hash = String.Empty;
        byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(password), 0, Encoding.UTF8.GetByteCount(password));
        foreach (byte bit in crypto)
        {
            hash += bit.ToString("x2");
        }
        return hash;
    }

Merci encore Quuxplusone pour le merveilleux et la réponse détaillée! :)

-5voto

YoeriDS Points 35

Vous devriez saler votre mot de passe avant de le hacher:

 private const string _salt = "P&0myWHq";    

private static string CalculateHashedPassword(string clearpwd)
{
    using (var sha = SHA256.Create())
    {
       var computedHash = sha.ComputeHash(Encoding.Unicode.GetBytes(clearpwd+_salt));
       return Convert.ToBase64String(computedHash);
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X