CÓMO: Calcular y comparar valores hash mediante C# .NET



No hay soporte técnico disponible para la versión Beta de este producto. Si desea información acerca de cómo obtener soporte técnico para una versión Beta, consulte la documentación incluida con los archivos del producto o busque en el sitio Web desde el que descargó la versión.




Para obtener una versión de Microsoft Visual Basic .NET de este artículo, consulte 301053 .

En esta tarea

Resumen

Las clases System.Security.Cryptography de Microsoft .NET Framework facilitan el cálculo de los valores hash de los datos de origen. En este artículo se muestra cómo obtener un valor hash y cómo comparar dos valores hash para comprobar si son idénticos.


Requisitos

La lista siguiente describe el hardware, el software, la infraestructura y los service pack recomendados que se necesitarán:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows 2000 Advanced Server o Windows NT 4.0 Server
  • Microsoft Visual C# .NET

Calcular un valor hash

Resulta sencillo generar y comparar valores hash con los recursos criptográficos que se incluyen en el espacio de nombres System.Security.Cryptography. Dado que todas las funciones de hash reciben entrada del tipo Byte[], podría ser necesario convertir el origen en una matriz de bytes para calcular los valores hash. Para crear un hash para un valor de cadena, siga estos pasos:
  1. Abra Visual Studio .NET.
  2. Cree una nueva aplicación de consola en Microsoft C#. Visual C# .NET crea una clase pública junto con un método Main() vacío.
  3. Utilice la directiva using en los espacios de nombres System,
    System.Security.Cryptography y System.Text, de manera que no se le pida que califique las declaraciones de estos espacios de nombres más tarde en el código. Debe utilizar estas instrucciones antes que cualquier otra declaración.
    using System;
    using System.Security.Cryptography;
    using System.Text;
  4. Declare una variable de cadena para almacenar los datos de origen y dos matrices de bytes (de tamaño indefinido) para almacenar los bytes de origen y el valor de hash resultante.
    string sSourceData;
    byte[] tmpSource;
    byte[] tmpHash;
  5. Utilice el método GetBytes(), que es un miembro de la clase System.Text.ASCIIEncoding, para convertir la cadena de origen en una matriz de bytes (requerida como entrada para la función de hashing).
    sSourceData = "MySourceData";
    //Crea una matriz de bytes de los datos de origen.
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);
  6. Calcule el hash de MD5 de los datos de origen con una llamada a ComputeHash en una instancia de la clase MD5CryptoServiceProvider. Tenga en cuenta que para calcular otro valor de hash, tendrá que crear otra instancia de la clase.
    //Calcula hash a partir de los datos de origen.
    tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
  7. La matriz de bytes tmpHash almacena ahora el valor de hash calculado (128-bit value=16 bytes) de los datos de origen. A menudo resulta útil mostrar o almacenar un valor como éste en forma de cadena hexadecimal, que se obtiene del siguiente modo:
    Console.WriteLine(ByteArrayToString(tmpHash));
    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();
    }
  8. Guarde y después ejecute el código para ver la cadena hexadecimal resultante del valor de origen.

Comparar dos valores hash

Uno de los objetivos de la creación de un hash de los datos de origen es el de proporcionar una forma para ver si los datos han cambiado con el tiempo o para comparar dos valores sin llegar a trabajar con los valores reales. En ambos casos, deberá comparar los dos valores de hash calculados, lo que resulta sencillo si ambos están almacenados en forma de cadenas hexadecimales (como en el último paso de la sección anterior). No obstante, es bastante probable que ambos estén en forma de matrices de bytes. El siguiente código, que continúa a partir del código creado en la sección anterior, muestra cómo comparar dos matrices de bytes.
  1. Justo a continuación de la creación de una cadena hexadecimal, cree un nuevo valor de hash a partir de los datos de origen nuevos.
    sSourceData = "NotMySourceData";
    tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

    byte[] tmpNewHash;

    tmpNewHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
  2. La forma más directa de comparar dos matrices de bytes es recorrerlas, y comparar cada elemento concreto con su homólogo en el segundo valor. Si alguno de los elementos es diferente o las dos matrices no son del mismo tamaño, los dos valores no son iguales.
    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("Los dos valores de hash son iguales");
    Else
    Console.WriteLine("Los dos valores de hash no son iguales");
    Console.ReadLine();
  3. Guarde y después ejecute el proyecto para ver la cadena hexadecimal creada a partir del primer valor de hash y para averiguar si el nuevo hash es igual al original.

Lista completa de código

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

namespace ComputeAHash_csharp
{
/// <summary>
/// Descripción de resumen para Class1.
/// </summary>
class Class1
{
static void Main(string[] args)
{
string sSourceData;
byte[] tmpSource;
byte[] tmpHash;
sSourceData = "MySourceData";
//Crea una matriz de bytes de los datos de origen
tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

//Calcula hash a partir de los datos de origen
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("Los dos valores de hash son iguales");
Else
Console.WriteLine("Los dos valores de hash no son iguales");
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();
}
}
}

REFERENCIAS

Para obtener más información acerca del uso de las características de cifrado de Microsoft .NET y la criptografía en general, consulte los siguientes vínculos:
Propiedades

Id. de artículo: 307020 - Última revisión: 20 oct. 2006 - Revisión: 1

Comentarios