Usar o Visual C# para calcular e comparar valores de hash

Este artigo passo a passo mostra como obter um valor de hash e como comparar dois valores de hash com marcar se eles são idênticos usando o Visual C#. Ele também fornece um exemplo de código para mostrar como fazer essa tarefa.

Versão original do produto: Visual C#
Número original do KB: 307020

Resumo

Este artigo refere-se aos seguintes namespaces da Biblioteca de Classes da Microsoft .NET Framework:

  • System.Security.Cryptography
  • System.Text

A System.Security.Cryptography classe no .NET Framework facilita a computação de um valor de hash para seus dados de origem.

Calcular um valor de hash

É fácil gerar e comparar valores de hash usando os recursos criptográficos contidos no System.Security.Cryptography namespace. Como todas as funções de hash levam entrada do tipo Byte[], talvez seja necessário converter a origem em uma matriz de bytes antes de ser hashed. Para criar um hash para um valor de cadeia de caracteres, siga estas etapas:

  1. Abra o Visual Studio .NET ou o Visual Studio.

  2. Criar um novo aplicativo de console no Visual C# .NET ou no Visual C# cria uma classe pública para você, juntamente com um método vazio Main() .

    Observação

    No Visual C#. NET, Class1.cs é criado por padrão. No Visual C#, Program.cs é criado por padrão.

  3. Use a using diretiva nos Systemnamespaces , System.Security.Cryptographye System.Text para que você não seja obrigado a qualificar declarações desses namespaces posteriormente em seu código. Essas instruções devem ser usadas antes de qualquer outra declaração.

    using System;
    using System.Security.Cryptography;
    using System.Text;
    
  4. Declare uma variável de cadeia de caracteres para manter seus dados de origem e duas matrizes de bytes (de tamanho indefinido) para manter os bytes de origem e o valor de hash resultante.

    string sSourceData;
    byte[] tmpSource;
    byte[] tmpHash;
    
  5. Use o GetBytes() método da classe para converter sua cadeia de caracteres de origem System.Text.ASCIIEncoding em uma matriz de bytes (necessária como entrada para a função de hash).

    sSourceData = "MySourceData";
    //Create a byte array from source data.
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    
  6. Compute o hash MD5 para seus dados de origem chamando ComputeHash uma instância da MD5CryptoServiceProvider classe.

    Observação

    Para calcular outro valor de hash, você precisará criar outra instância da classe.

    //Compute hash based on source data.
    tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  7. A tmpHash matriz de bytes agora contém o valor de hash computado (valor de 128 bits=16 bytes) para seus dados de origem. Geralmente, é útil exibir ou armazenar um valor como esta como uma cadeia de caracteres hexadecimal, que o código a seguir realiza:

    Console.WriteLine(ByteArrayToString(tmpHash));
    static string ByteArrayToString(byte[] arrInput)
    {
        int i;
        StringBuilder sOutput = new StringBuilder(arrInput.Length);
        for (i=0;i < arrInput.Length; i++)
        {
            sOutput.Append(arrInput[i].ToString("X2"));
        }
        return sOutput.ToString();
    }
    
  8. Salve e execute seu código para ver a cadeia de caracteres hexadecimal resultante para o valor de origem.

Comparar dois valores de hash

As finalidades de criar um hash a partir de dados de origem são:

  • Fornecendo uma maneira de ver se os dados foram alterados ao longo do tempo.
  • Comparando dois valores sem nunca trabalhar com os valores reais.

Em ambos os casos, você precisa comparar dois hashes computados. É fácil se ambos forem armazenados como cadeias de caracteres hexadecimal (como na última etapa da seção acima). Mas é possível que ambos estejam na forma de matrizes de bytes. O código a seguir, que continua do código criado na seção anterior, mostra como comparar duas matrizes de bytes.

  1. Logo abaixo da criação de uma cadeia de caracteres hexadecimal, crie um novo valor de hash com base em novos dados de origem.

    sSourceData = "NotMySourceData";
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    byte[] tmpNewHash;
    tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  2. A maneira mais simples de comparar duas matrizes de bytes é fazer loop através das matrizes, comparando cada elemento individual com seu equivalente a partir do segundo valor. Se algum elemento for diferente ou se as duas matrizes não tiverem o mesmo tamanho, os dois valores não serão iguais.

    bool bEqual = false;
    if (tmpNewHash.Length == tmpHash.Length)
    {
        int i=0;
        while ((i < tmpNewHash.Length) && (tmpNewHash[i] == tmpHash[i]))
        {
            i += 1;
        }
        if (i == tmpNewHash.Length)
        {
            bEqual = true;
        }
    }
    
    if (bEqual)
        Console.WriteLine("The two hash values are the same");
    else
        Console.WriteLine("The two hash values are not the same");
    Console.ReadLine();
    
  3. Salve e execute seu projeto para exibir a cadeia de caracteres hexadecimal criada a partir do primeiro valor de hash. Descubra se o novo hash é igual ao original.

Lista de código completa

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

namespace ComputeAHash_csharp
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        static void Main(string[] args)
        {
            string sSourceData;
            byte[] tmpSource;
            byte[] tmpHash;
            sSourceData = "MySourceData";
            //Create a byte array from source data
            tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

            //Compute hash based on source data
            tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
            Console.WriteLine(ByteArrayToString(tmpHash));

            sSourceData = "NotMySourceData";
            tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

            byte[] tmpNewHash;

            tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);

            bool bEqual = false;
            if (tmpNewHash.Length == tmpHash.Length)
            {
                int i=0;
                while ((i < tmpNewHash.Length) && (tmpNewHash[i] == tmpHash[i]))
                {
                    i += 1;
                }
                if (i == tmpNewHash.Length)
                {
                    bEqual = true;
                }
            }

            if (bEqual)
                Console.WriteLine("The two hash values are the same");
            else
                Console.WriteLine("The two hash values are not the same");
            Console.ReadLine();
        }

        static string ByteArrayToString(byte[] arrInput)
        {
            int i;
            StringBuilder sOutput = new StringBuilder(arrInput.Length);
            for (i=0;i < arrInput.Length -1; i++)
            {
                sOutput.Append(arrInput[i].ToString("X2"));
            }
            return sOutput.ToString();
        }
    }
}

Referências

Para obter mais informações sobre como usar os recursos criptográficos do .NET Framework, consulte .NET.