Usare Visual C# per calcolare e confrontare i valori hash

Questo articolo dettagliato illustra come ottenere un valore hash e come confrontare due valori hash per verificare se sono identici usando Visual C#. Fornisce anche un esempio di codice per illustrare come eseguire questa attività.

Versione originale del prodotto: Oggetto visivo C#
Numero KB originale: 307020

Riepilogo

Questo articolo fa riferimento agli spazi dei nomi della libreria di classi di Microsoft .NET Framework seguenti:

  • System.Security.Cryptography
  • System.Text

La System.Security.Cryptography classe in .NET Framework semplifica il calcolo di un valore hash per i dati di origine.

Calcolare un valore hash

È facile generare e confrontare i valori hash usando le risorse di crittografia contenute nello spazio dei System.Security.Cryptography nomi . Poiché tutte le funzioni hash accettano l'input di tipo Byte[], potrebbe essere necessario convertire l'origine in una matrice di byte prima dell'hash. Per creare un hash per un valore stringa, seguire questa procedura:

  1. Aprire Visual Studio .NET o Visual Studio.

  2. Creare una nuova applicazione console in Visual C# .NET o in Visual C# crea automaticamente una classe pubblica insieme a un metodo vuoto Main() .

    Nota

    In Visual C#. NET, Class1.cs viene creato per impostazione predefinita. In Visual C# Program.cs viene creato per impostazione predefinita.

  3. Usare la using direttiva negli Systemspazi dei nomi , System.Security.Cryptographye System.Text in modo che non sia necessario qualificare le dichiarazioni da questi spazi dei nomi più avanti nel codice. Queste istruzioni devono essere usate prima di qualsiasi altra dichiarazione.

    using System;
    using System.Security.Cryptography;
    using System.Text;
    
  4. Dichiarare una variabile stringa per contenere i dati di origine e due matrici di byte (di dimensioni non definite) per contenere i byte di origine e il valore hash risultante.

    string sSourceData;
    byte[] tmpSource;
    byte[] tmpHash;
    
  5. Usare il GetBytes() metodo della classe per convertire la System.Text.ASCIIEncoding stringa di origine in una matrice di byte (necessaria come input per la funzione hash).

    sSourceData = "MySourceData";
    //Create a byte array from source data.
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    
  6. Calcolare l'hash MD5 per i dati di origine chiamando ComputeHash su un'istanza della MD5CryptoServiceProvider classe .

    Nota

    Per calcolare un altro valore hash, è necessario creare un'altra istanza della classe .

    //Compute hash based on source data.
    tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  7. La tmpHash matrice di byte contiene ora il valore hash calcolato (valore a 128 bit=16 byte) per i dati di origine. Spesso è utile visualizzare o archiviare un valore come questo come stringa esadecimale, funzionalità gestito dal codice seguente:

    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. Salvare ed eseguire il codice per visualizzare la stringa esadecimale risultante per il valore di origine.

Confrontare due valori hash

Gli scopi della creazione di un hash dai dati di origine sono:

  • Consente di verificare se i dati sono stati modificati nel tempo.
  • Confronto di due valori senza mai usare i valori effettivi.

In entrambi i casi, è necessario confrontare due hash calcolati. È facile se sono entrambi archiviati come stringhe esadecimali (come nell'ultimo passaggio della sezione precedente). Ma è possibile che entrambi siano sotto forma di matrici di byte. Il codice seguente, che continua dal codice creato nella sezione precedente, illustra come confrontare due matrici di byte.

  1. Appena sotto la creazione di una stringa esadecimale, creare un nuovo valore hash basato sui nuovi dati di origine.

    sSourceData = "NotMySourceData";
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
    byte[] tmpNewHash;
    tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    
  2. Il modo più semplice per confrontare due matrici di byte consiste nel eseguire un ciclo tra le matrici, confrontando ogni singolo elemento con la relativa controparte del secondo valore. Se gli elementi sono diversi o se le due matrici non hanno le stesse dimensioni, i due valori non sono uguali.

    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. Salvare ed eseguire il progetto per visualizzare la stringa esadecimale creata dal primo valore hash. Verificare se il nuovo hash è uguale all'originale.

Elenco di codice completo

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

Riferimenti

Per altre informazioni su come usare le funzionalità di crittografia di .NET Framework, vedere .NET.