Hashing un archivo grande en un sistema integrado

7

Estoy tratando de encontrar una manera de verificar la autenticidad de un archivo que estoy descargando de un servidor a un sistema integrado. Estoy pensando en usar un hash (SHA256 preferiblemente). Mi principal preocupación es que el tamaño del archivo puede ser demasiado grande para cargarlo en un búfer y pasarlo a la función de hashing.

Al buscar en línea, encontré esta respuesta ( enlace ) que habla de calcular un hash tree en lugar de un hash para todo el archivo. ¿Es este un enfoque válido? ¿Alguien tiene algún consejo para hacer esto de una manera diferente?

    
pregunta Aravind 12.02.2018 - 22:34
fuente

3 respuestas

5

Mientras reciba el archivo en orden de principio a fin, puede calcular el hash de manera incremental. Cualquier API de criptografía que sea adecuada para sistemas incrustados (y la mayoría de los que no lo son) le permite calcular el hash al pasar fragmentos sucesivos de la entrada. Cada vez que reciba un fragmento, alimente la entrada al cálculo de hash y adjúntelo a un archivo. Cuando finalice la transmisión, finalice el cálculo de hash y borre el archivo si el hash es incorrecto.

Tenga en cuenta que un hash solo puede verificar la integridad de un archivo, no la autenticidad. Esto significa que el dispositivo necesita conocer el valor de hash de antemano, por lo que debe transmitir el hash a través de otro canal. Esto se hace normalmente utilizando un canal lento pero confiable para transmitir el hash (por ejemplo, TLS de extremo a extremo a un servidor confiable) y un canal con más ancho de banda pero menos seguridad para el archivo en sí (por ejemplo, un mecanismo de transmisión).

Un hash tree solo es útil si necesita poder verificar partes del archivo de forma independiente sin tener que recuperar todo el archivo. Si está obteniendo el archivo de forma secuencial y completa, no es útil.

    
respondido por el Gilles 12.02.2018 - 22:57
fuente
1

Prácticamente todas las funciones hash que existen, y ciertamente todas las funciones hash que vale la pena usar (sí, eso incluye SHA-256), se pueden usar de forma continua. No es necesario darle el archivo completo para que se copie en un solo fragmento; en su lugar, puede alimentar el archivo en trozos pequeños y obtener el valor hash final cuando haya terminado.

    
respondido por el Mark 12.02.2018 - 22:38
fuente
1

Los requisitos de memoria para SHA-2 son independientes del tamaño del mensaje.

La forma en que funcionan los hash criptográficos no es exactamente intuitiva. Todo lo que es es una función que comienza con un valor inicial y toma una sola entrada de su tamaño de bloque, que permuta el resumen. No hay un estado interno para el hash, y cada bloque subsiguiente simplemente permuta el resumen un poco más. Un resumen dado, más un bloque de entrada dado, siempre resultará en el mismo resumen nuevo. Esta es una de las ideas detrás de la construcción Merkle – Damgård , que MD5 y Uso SHA-2. La operación de hash en cada bloque de entrada es individual y atómica, sin respetar el mensaje completo (aunque el bloque de relleno final codifica la longitud total del mensaje que se está copiando). Hashear un archivo simplemente implica hacer esto repetidamente, comenzando con un valor inicial especificado por el estándar, y terminando cuando no haya más bloques para ser hash. Solo necesita almacenar tres cosas para calcular un resumen de SHA-2:

  • El resumen actual, o el valor inicial. Este es el tamaño del hash.
  • El siguiente bloque de entrada (512 bits o 1024 bits, dependiendo del tamaño de hash).
  • El estado interno durante la operación de hash, que es el mismo para cada bloque.

De FIPS-180-4 § 5.2, el mensaje se analiza al dividirlo en bloques individuales:

5.2    Parsing the message
The message and its padding must be parsed into N m-bit blocks.

5.2.1  SHA-1, SHA-224 and SHA-256
For SHA-1, SHA-224 and SHA-256, the message and its padding are parsed into N
512-bit blocks, M(1), M(2),..., M(N). Since the 512 bits of the input block may be
expressed as sixteen 32-bit words, the first 32 bits of message block i are
denoted M0(i), the next 32 bits are M1(i), and so on up to M15(i).

5.2.2  SHA-334, SHA-512, SHA-512/224 and SHA-512/256
For SHA-384, SHA-512, SHA-512/224 and SHA-512/256, the message and its padding are
parsed into N1024-bit blocks, M(1), M(2),..., M(N). Since the 1024 bits of the input
block may be expressed as sixteen 64-bit words, the first 64 bits of message block
i are denoted M0(i), the next 64 bits are M1(i), and so on up to M15(i).

Para SHA-1, SHA-256 y SHA-512, el tamaño del estado interno es tan grande como el resumen (los otros hashes como SHA-224 y SHA-512/224 son versiones simplemente truncadas de versiones más grandes, con diferentes valores iniciales). Esto significa que, para su caso de uso con SHA-256, solo necesita poder almacenar 256 bits (32 bytes) de datos para calcular el resumen de datos de cualquier tamaño, desde 0 bits hasta 2 64 - 1 bits (este límite se debe al relleno utilizado, que codifica el tamaño del mensaje en un bloque de 64 bits). Varias optimizaciones pueden aumentar los requisitos de memoria, pero no lo suficiente como para preocuparse por un sistema integrado.

Algunas funciones hash más nuevas tienen un estado interno mayor que el tamaño de su resumen de salida para evitar ataques de extensión de longitud , donde, sin conocer m y tener solo su resumen, puede calcular el resumen de m ', donde m' comienza con el contenido de m . SHA-3 (independientemente del tamaño del compendio), por ejemplo, tiene un estado interno mayor de 1600 bits para evitarlo. Asegura que cualquier operación de hashing individual depende del estado interno, que no se revela al final cuando se libera el resumen final.

    
respondido por el forest 13.02.2018 - 04:13
fuente

Lea otras preguntas en las etiquetas