2010-07-06 13 views
12

Me he encontrado con un problema interesante .. Parece que ComputeHash() para un hash "HMACSHA256" no se comporta de manera determinista ... si creo dos instancias de HashAlgorithm usando HashAlgorithm.Create ("HMACSHA256") .. Y ejecuto ComputeHash, obtengo dos resultados diferentes. A continuación se muestra un ejemplo de clase estática que muestra este comportamiento.¿Por qué ComputeHash no actúa de manera determinista?

internal static string HashPassword(byte[] bAll) 
{ 
    using (HashAlgorithm s = HashAlgorithm.Create("HMACSHA256")) 
    { 
     return Convert.ToBase64String(s.ComputeHash(bAll)); 
    } 
} 

También he tratado de hacer la llamada que no es estática (en realidad comenzado no estática, y tengo dobles y triples y quadrudruple comprobado mi matriz de entrada .. su absolutamente el mismo en cada llamada .. I' incluso he hecho cosas en la ventana immidiate como:

Convert.ToBase64String(HashAlgorithm.Create("HMACSHA256").ComputeHash(bAll) 

Y corriendo el doble que en la ventana immidiates a través de un punto de interrupción en el método devuelve dos valores hash diferentes ..

sé Hash se supone que debe ser determinista. Entonces, ¿qué ocurre? ¿Algo está pasando con la ejecución? en un depurador? ¿O alguna otra idea? Realmente esto es sólo extraño para dos palabras ahora mismo :-P ..

Gracias Josh

+3

¿Tiene algún breve ejemplo de muestra que presente este problema? ¿Hay algo que cambie 'bAll' entre o durante las llamadas? –

+4

HMAC es un hash con clave.No veo la clave en tu código de ejemplo. Creo que la clave se establece aleatoriamente si no se especifica una explícitamente. – dtb

+0

nada cambia entre llamadas .. Como dije, incluso he hecho esto desde la ventana de Immidiates ... Aquí hay 4 llamadas desde mi ventana de Immidiates ... sí, no son perfectas porque debe deshacerse del algoritmo HashAlgorithm, pero los resultados son mismo a través de la ventana Immidiates o el método. (Los incluiré en el próximo comentario, porque no tengo espacio para copiarlos, pégalos aquí) –

Respuesta

24

HMAC es una clave hash. No veo la clave en tu código de ejemplo.

HashAlgorithm.Create("HMACSHA256") crea una instancia de HashAlgorithm, por lo que no sabe nada sobre una clave. Probablemente sólo llama this HMACSHA256 Constructor:

public HMACSHA256()

Inicializa una nueva instancia de la clase con un HMACSHA256 clave generada aleatoriamente.

¿Quieres this constructor:

public HMACSHA256(byte[] key)

Inicializa una nueva instancia de la clase HMACSHA256 con los datos clave especificadas.

Si no desea a codificar el algoritmo HMAC, puede utilizar KeyedHashAlgorithm.Create y suministrar una clave específica estableciendo la propiedad KeyedHashAlgorithm.Key.

Si no desea utilizar una clave, utilice un hash sin clave como SHA256.

+0

Su mejor opción es usar ['KeyedHashAlgorithm.Create'] (http://msdn.microsoft.com/en-us/library/s5zz2x4d.aspx). Lección aprendida: ¡conoce tus hash! – Randolpho

+0

Voy a profundizar en las cosas del proveedor y averiguar por qué MS estaba/está por defecto en un hash con clave, pero usando HashAlgorithm.Create() cuando lo genera. puede ser que estoy usando una fuente de 2.0 ASP basado en ASP.NET Provider Pack con framework 4.0. De todos modos, gracias por apuntarme en la dirección correcta. –

+0

@Josh: Hay algunos lugares donde la EM tiene aleatoriedad "sorprendente". Por ejemplo, algunas configuraciones 'CypherMode' para el cifrado usan un Vector de inicialización aleatorio si no lo especifica. La parte divertida es cuando tu cifrado y descifrado funcionan perfectamente para todos los primeros 8 bytes de tus datos. Creo que tomaron una buena decisión aquí. Prefiero que un programa falle rápido porque no entiendo los parámetros de seguridad que necesita antes que tener un estado predeterminado de "trabajo" pero menos seguro. – Brian

3

Necesita una clave para HMACSHA256. La clave será aleatoria si no se pasa al constructor.

5

Simplemente añadiendo a esto con la esperanza de salvar a alguien el dolor de cabeza que sufrí.

En el caso de .Net Membership Provider, asegúrese de tener la configuración en su web.config o app.config. De lo contrario, generará automáticamente su propia clave ... fallará en la autenticación, y luego se reirá beligerante al final.

Cuestiones relacionadas