2011-04-27 6 views
10

Tengo tres campos: string Title, byte[] Body y byte[] Data, de los cuales quiero calcular un solo hash como verificación para asegurarme de que no se hayan manipulado o dañado.Hashing multiple byte [] 's juntos en un solo hash con C#?

En Python, puedo usar md5.update() varias veces seguidas para realizar esto. Pero no puedo encontrar una capacidad similar en C#. Para usar MD5.ComputeHash() necesitaría copiar todas mis fuentes en un solo byte [], que es un paso que me gustaría evitar.

¿Cómo puedo unir todo en un hash sin tener que copiar los datos en un búfer temporal?

+1

¿Por qué no utilizar la variable de temperatura? –

+1

Y por cierto, supongo que Python crea una única matriz de bytes debajo del capó ... – digEmAll

+4

¿Sabía que MD5 está roto, ¿verdad? Usted dice que está usando el hash para detectar la manipulación, pero es computacionalmente factible para el atacante alterar el documento sin cambiar el hash.Debería usar SHA256 o algún otro algoritmo hash que no tenga problemas conocidos de resistencia a la colisión. –

Respuesta

13

Casi todos los algoritmos hash están diseñados de manera que puedan ser alimentados sucesivamente con los datos en múltiples bloques. El resultado es el mismo que si se procesaran todos los datos a la vez.

Crea una instancia de p. Ej. MD5CryptoServiceProvider y llamar a la TransformBlock Method para cada bloque y el TransformFinalBlock Method para el último bloque:

MD5 md5 = new MD5CryptoServiceProvider(); 

// For each block: 
md5.TransformBlock(block, 0, block.Length, block, 0); 

// For last block: 
md5.TransformFinalBlock(block, 0, block.Length); 

// Get the hash code 
byte[] hash = md5.Hash; 
+0

Parece una mezcla de idiomas? –

+0

¿Puede proporcionar un ejemplo de código? Veo ese método pero su uso me elude. ¿Cómo puedo evitar que sobrescriba el resultado anterior, por ejemplo? –

+0

Transformar (final) El bloque funciona básicamente de la misma manera que la actualización, es decir, actualiza el estado interno de la instancia de MD5 con los datos nuevos. He añadido un ejemplo (aunque no probado). – dtb

-1

Debe combinarlos todos en una sola variable y luego calcular la Hash MD5. No veo ningún atajo allí.

Usted ve, la mayoría de las soluciones propuestas aquí sólo tratan ya sea para ejecutar varios comandos en la misma línea ("trazadores de líneas uno") o implementan algo que "bajo el capó" combinar sus campos y luego Hash ...

1

Usando plain .NET, no creo que haya una forma de actualizar y hash MD5. Sin embargo, Windows tiene una función MD5Update definida en crypt.dll. Podría usar Interop para aprovechar esto, supongo.

De lo contrario, existe una implementación de un equivalente PHP en .NET C#, que se encuentra aquí en la SO: Problem porting PHP crypt() function to C#

PS: Sin duda para la solución combinada variable TEMP :-)

+0

... downvoters son bienvenidos para explicar su punto de vista. –

0

que pueda crear un Hash sobre los valores de Hash.

MD5 md5 = System.Security.Cryptography.MD5.Create(); 
byte[] totalHash= md5.ComputeHash(md5.ComputeHash(part1).Concat(md5t.computeHash(part2))); 

no crea una copia de la matriz de bytes pero hashes una concatenación de los valores hash.

+0

+1: No sé por qué obtuviste -1'd, es una solución razonable IMO (aunque @dtb es mejor :)). –

+0

solo me pregunté por qué obtuve el -1. Pero estoy de acuerdo con que el dtb es mejor :-) – fixagon

+1

esto reduce la fuerza de la criptografía (en un MD5 ya debilitado), lo cual es potencialmente importante, así que debe evitarse. (No es que yo -1'd pero supongo que esa fue la razón). No creo que sea tan horrible como la sugerencia de Guffa, pero no es una buena idea rodar tu propia criptografía de esta manera (incluso si los bloques de construcción son buenos) – ShuggyCoUk

0

Llamar a la función ComputeHash en tres valores diferentes va a crear tres resultados de la matriz de bytes diferentes. Esos resultados tendrán que combinarse de alguna manera para producir un solo hash. No hay forma de evitar este hecho. Creará tres objetos nuevos en el montón. Calculará un hash (una operación bastante lenta) tres veces en lugar de solo uno.

Creo que la forma más eficaz de hacer lo que desea es seguir adelante y copiar los valores de origen en una única matriz de bytes y tomar el hash de eso.

No dice por qué quiere evitar este enfoque. Creo que gana en términos de simplicidad y facilidad de mantenimiento. Es el enfoque obvio que se documenta a sí mismo. Es el método más eficiente. Realmente no veo un lado negativo.