web-dev-qa-db-fra.com

Calculer un hachage MD5 à partir d'une chaîne

J'utilise le code C # suivant pour calculer un hachage MD5 à partir d'une chaîne . Il fonctionne bien et génère une chaîne hexagonale de 32 caractères comme celle-ci: 900150983cd24fb0d6963f7d28e17f72

string sSourceData;
byte[] tmpSource;
byte[] tmpHash;
sSourceData = "MySourceData";

//Create a byte array from source data.
tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);

// and then convert tmpHash to string...

Existe-t-il un moyen d'utiliser un code comme celui-ci pour générer une chaîne hexadécimale de 16 caractères (ou une chaîne de 12 caractères)? Une chaîne hexagonale de 32 caractères est bonne, mais je pense que ce sera ennuyeux pour le client de saisir le code!

91
user1422847

Selon MSDN

Créer MD5:

   public static string CreateMD5(string input)
    {
        // Use input string to calculate MD5 hash
        using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
        {
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hashBytes = md5.ComputeHash(inputBytes);

            // Convert the byte array to hexadecimal string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hashBytes.Length; i++)
            {
                sb.Append(hashBytes[i].ToString("X2"));
            }
            return sb.ToString();
        }
    }
134
Anant Dabhi
// given, a password in a string
string password = @"1234abcd";

// byte array representation of that string
byte[] encodedPassword = new UTF8Encoding().GetBytes(password);

// need MD5 to calculate the hash
byte[] hash = ((HashAlgorithm) CryptoConfig.CreateFromName("MD5")).ComputeHash(encodedPassword);

// string representation (similar to UNIX format)
string encoded = BitConverter.ToString(hash)
   // without dashes
   .Replace("-", string.Empty)
   // make lowercase
   .ToLower();

// encoded contains the hash you are wanting
81
Michael

Vous pouvez utiliser Convert.ToBase64String pour convertir une sortie 16 octets de MD5 en une chaîne de ~ 24 caractères. Un peu mieux sans réduire la sécurité. (j9JIbSY8HuT89/pwdC8jlw== pour votre exemple)

7
L.B

Cela dépend entièrement de ce que vous essayez d’atteindre. Techniquement, vous pouvez simplement prendre les 12 premiers caractères du résultat du hachage MD5, mais la spécification de MD5 consiste à générer un caractère 32 caractères.

Réduire la taille du hachage réduit la sécurité et augmente les risques de collision et de panne du système.

Peut-être que si vous nous laissez savoir plus sur ce que vous essayez de réaliser, nous pourrons peut-être aider davantage.

7
KingCronus

J'essayais de créer une représentation sous forme de chaîne du hachage MD5 à l'aide de LINQ. Cependant, aucune des réponses n'était une solution LINQ, ce qui l'ajoutait donc à la panoplie de solutions disponibles. 

string result;
using (MD5 hash = MD5.Create())
{
    result = String.Join
    (
        "",
        from ba in hash.ComputeHash
        (
            Encoding.UTF8.GetBytes(observedText)
        ) 
        select ba.ToString("x2")
    );
}
6
craigdfrench

Chaîne de soutien et flux de fichiers.

exemples

string hashString = EasyMD5.Hash("My String");

string hashFile = EasyMD5.Hash(System.IO.File.OpenRead("myFile.txt"));

-

   class EasyMD5
        {
            private static string GetMd5Hash(byte[] data)
            {
                StringBuilder sBuilder = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                    sBuilder.Append(data[i].ToString("x2"));
                return sBuilder.ToString();
            }

            private static bool VerifyMd5Hash(byte[] data, string hash)
            {
                return 0 == StringComparer.OrdinalIgnoreCase.Compare(GetMd5Hash(data), hash);
            }

            public static string Hash(string data)
            {
                using (var md5 = MD5.Create())
                    return GetMd5Hash(md5.ComputeHash(Encoding.UTF8.GetBytes(data)));
            }
            public static string Hash(FileStream data)
            {
                using (var md5 = MD5.Create())
                    return GetMd5Hash(md5.ComputeHash(data));
            }

            public static bool Verify(string data, string hash)
            {
                using (var md5 = MD5.Create())
                    return VerifyMd5Hash(md5.ComputeHash(Encoding.UTF8.GetBytes(data)), hash);
            }

            public static bool Verify(FileStream data, string hash)
            {
                using (var md5 = MD5.Create())
                    return VerifyMd5Hash(md5.ComputeHash(data), hash);
            }
        }
5
Think Big

Je suppose qu'il est préférable d'utiliser le codage UTF-8 dans la chaîne MD5.

public static string MD5(this string s)
{
    using (var provider = System.Security.Cryptography.MD5.Create())
    {
        StringBuilder builder = new StringBuilder();                           

        foreach (byte b in provider.ComputeHash(Encoding.UTF8.GetBytes(s)))
            builder.Append(b.ToString("x2").ToLower());

        return builder.ToString();
    }
}
3
Tomas Kubes

Un hachage MD5 est de 128 bits, vous ne pouvez donc pas le représenter en hexadécimal avec moins de 32 caractères ...

3
Thomas Levesque
System.Text.StringBuilder hash = new System.Text.StringBuilder();
        System.Security.Cryptography.MD5CryptoServiceProvider md5provider = new System.Security.Cryptography.MD5CryptoServiceProvider();
        byte[] bytes = md5provider.ComputeHash(new System.Text.UTF8Encoding().GetBytes(YourEntryString));

        for (int i = 0; i < bytes.Length; i++)
        {
            hash.Append(bytes[i].ToString("x2")); //lowerCase; X2 if uppercase desired
        }
        return hash.ToString();
3
Kristian Jay

https://docs.Microsoft.com/en-us/dotnet/api/system.security.cryptography.md5?view=netframework-4.7.2

using System;
using System.Security.Cryptography;
using System.Text;

    static string GetMd5Hash(string input)
            {
                using (MD5 md5Hash = MD5.Create())
                {

                    // Convert the input string to a byte array and compute the hash.
                    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

                    // Create a new Stringbuilder to collect the bytes
                    // and create a string.
                    StringBuilder sBuilder = new StringBuilder();

                    // Loop through each byte of the hashed data 
                    // and format each one as a hexadecimal string.
                    for (int i = 0; i < data.Length; i++)
                    {
                        sBuilder.Append(data[i].ToString("x2"));
                    }

                    // Return the hexadecimal string.
                    return sBuilder.ToString();
                }
            }

            // Verify a hash against a string.
            static bool VerifyMd5Hash(string input, string hash)
            {
                // Hash the input.
                string hashOfInput = GetMd5Hash(input);

                // Create a StringComparer an compare the hashes.
                StringComparer comparer = StringComparer.OrdinalIgnoreCase;

                return 0 == comparer.Compare(hashOfInput, hash);

            }
0
KhaledDev
StringBuilder sb= new StringBuilder();
for (int i = 0; i < tmpHash.Length; i++)
{
   sb.Append(tmpHash[i].ToString("x2"));
}
0
Suhrob Samiev

Une alternative plus rapide de la réponse existante pour .NET Core 2.1 et supérieur:

public static string CreateMD5(string s)
{
    using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
    {
        var encoding = Encoding.ASCII;
        var data = encoding.GetBytes(s);

        Span<byte> hashBytes = stackalloc byte[16];
        md5.TryComputeHash(data, hashBytes, out int written);
        if(written != hashBytes.Length)
            throw new OverflowException();


        Span<char> stringBuffer = stackalloc char[32];
        for (int i = 0; i < hashBytes.Length; i++)
        {
            hashBytes[i].TryFormat(stringBuffer.Slice(2 * i), out _, "x2");
        }
        return new string(stringBuffer);
    }
}

Vous pouvez l'optimiser encore plus si vous êtes sûr que vos chaînes sont suffisamment petites et remplacez encoding.GetBytes par unsafe int, alternative à GetBytes (caractères ReadOnlySpan, Span).

0
Tomas Kubes

Cette solution nécessite le c # 7.2 et tire parti de Span<T>. Quelle que soit la taille de l'entrée, cette opération alloue une quantité de mémoire fixe et est plus rapide que la réponse acceptée. Notez que vous devrez toujours appeler .Replace("-", string.Empty).ToLowerInvariant() pour formater le résultat si nécessaire.

public static string CreateMD5(ReadOnlySpan<char> input)
{
    var encoding = System.Text.Encoding.UTF8;
    var inputByteCount = encoding.GetByteCount(input);

    using (var md5 = System.Security.Cryptography.MD5.Create())
    {
        Span<byte> bytes = stackalloc byte[inputByteCount];
        Span<byte> destination = stackalloc byte[md5.HashSize / 8];

        encoding.GetBytes(input, bytes);

        // checking the result is not required because this only returns false if "(destination.Length < HashSizeValue/8)", which is never true in this case
        md5.TryComputeHash(bytes, destination, out int _bytesWritten);

        return BitConverter.ToString(destination.ToArray());
    }
}
0
Brad M