Hash rápido: ¿combinación de diferentes técnicas para identificar cambios en un archivo?


9

Quiero crear una forma rápida de detectar si un archivo puede o no ser el mismo. Para casi el 100% de seguridad, usaría un algoritmo hash existente, por ejemplo, SHA256. Sin embargo, se espera que los archivos sean archivos de video enormes con varios GB, por lo que calcular el hash SHA256 podría llevar algún tiempo, especialmente a través de la red.

Por lo tanto, quiero combinar otras técnicas diferentes:

  • tamaño del archivo: si el tamaño del archivo ha cambiado, el contenido ha cambiado (seguro)
  • hash de cabeza / cola
  • hash aleatorio

Los últimos 2 son parte de mi pregunta:

Supongo que en el encabezado hay cosas como:

  • velocidades de cuadro (por ejemplo, videos)
  • resolución (por ejemplo, videos, imágenes)
  • (archivo) longitud (por ejemplo, en cuadros, píxeles, etc.)
  • última fecha de cambio (por ejemplo, documentos de Word, no específicamente videos)

Por qué considero revisar la cola es:

  • MP3 tiene la información de la etiqueta allí
  • EXIF agrega datos personalizados al final si tengo razón

Los hashes aleatorios seleccionarían, por ejemplo, 126 regiones en posiciones aleatorias en el archivo con una longitud específica, por ejemplo, 64 kB y crearían un hash para ellos. Por supuesto que recuerdo las compensaciones para una comparación posterior. En general, usaría (1 + 126 + 1) * 64 kB de datos para mi hash, por lo que necesito leer solo 8 MB en lugar de varios GB para obtener el hash.

Tal vez es más una pregunta matemática ahora, pero: ¿qué tan probable es detectar un cambio usando la combinación de tamaño de archivo, encabezado, cola y datos aleatorios para generar esta suma rápida de hash?

Supongo que los archivos son siempre archivos legales. No hay beneficio en la manipulación de bytes individuales. El usuario usaría una herramienta de edición de video normal para cambiar los archivos.

ACTUALIZACIÓN : no acepté esta respuesta que vino de Crypto.StackExchange. Estoy de acuerdo en que mi propuesta no es criptográfica y no pretende ser segura. También estoy de acuerdo en que CRCing un archivo es rápido, pero en mi caso realmente necesito un hash. Explicaré por qué:

  • Se espera que mi aplicación guarde marcadores en videos. Se espera que mi base de datos guarde el hash de video y los marcadores.
  • Los usuarios a veces mueven o renombran archivos. Mi programa notará que un archivo ya no existe, pero no eliminará los marcadores de la base de datos. En cambio, cuando el mismo video se reproduce (accidentalmente) nuevamente, quiero reconocer que es (probablemente) el mismo archivo.
  • Se espera que los usuarios guarden archivos en unidades de red (NAS) y transmitan videos. Esos son almacenamientos tontos. No puedo instalar un componente del servidor. Y pueden ser bastante lentos, así que realmente no quiero el hash completo. Calcular un hash completo en un archivo de 3 GB lleva al menos 5 minutos a 10 MB / s, sin importar cuán rápido sea el algoritmo de hash.
  • Si el usuario ha editado el archivo, de alguna manera espero que el hash no coincida más, porque de lo contrario mostraría marcadores incorrectos.

Estaría bien con un ~ 80% de posibilidades de tener los marcadores correctos. ¿Cuántas piezas hash debo juntar y en qué parte del archivo estarían?


1
Mientras la manipulación maliciosa o la corrupción de archivos no sean una preocupación, no hay necesidad de nada de esto. Simplemente use un programa especializado para interpretar los encabezados del archivo multimedia, que debe contener las fechas y tamaños de codificación / etiquetado de las secuencias. Puede analizar la información de los medios para facilitar la comparación.

Además, la mayoría de los sistemas operativos mantienen una 'última fecha de modificación' disponible para cada archivo. Si no tiene que preocuparse por la manipulación malintencionada (esa última fecha de modificación generalmente puede ser establecida por alguien), puede ver eso y no molestarse con el contenido del archivo.
poncho

EXIF o MP3tag son casi inútiles para detectar cambios: muchos de los programas de manipulación no pueden tocarlos, por lo que retienen sus contenidos anteriores. Por ejemplo, EXIF ​​bien puede conservar la imagen original .

1
Pasando por "supongo que los archivos son siempre archivos legales", ¿supongo que no estás buscando ninguna seguridad? En este caso, estás en el sitio equivocado. La informática debería ser una mejor ayuda. Las respuestas que ha tenido aquí son irrelevantes si no desea seguridad, por lo que si este es el caso, sugeriría volver a publicar en Computer Science y aclarar ese punto en su pregunta reenviada.
Gilles 'SO- deja de ser malo'

2
1) El cálculo de hash real generalmente será barato en comparación con el IO. MD5 detectará todos los cambios no maliciosos y es bastante rápido. Especialmente si lo paralelizas. Necesitaría una RAID de SSD o algo similarmente rápido para superar su velocidad. 2) Para los archivos locales, el sistema operativo a menudo puede decirle si cambió. No solo la fecha del último cambio, también hay algunas API especializadas.
CodesInChaos

Respuestas:


8

Hay dos caras de su moneda:

  1. si desea hacerlo de forma segura, necesitará usar un hash criptográficamente seguro como SHA256 (los hash de cifrado deben ser rápidos, pero tienden a ser un poco lentos debido a restricciones de seguridad),
  2. cosas como los CRC son definitivamente más rápidos, pero nunca podrán ofrecer el mismo tipo de seguridad (especialmente cuando estamos hablando de eso).

Opción 1: CRC: hacerlo rápidamente al precio de la seguridad:

Si está justo después de la detección de cambios, busque una suma de verificación en lugar de un hash. Para eso se hicieron las sumas de comprobación: detectar rápidamente los cambios en un archivo o flujo de datos. ¡Pero tenga en cuenta que CRC fue diseñado para evitar errores de transmisión, no acciones maliciosas!

Prácticamente, CRC32 es el candidato más obvio (pero incluso un CRC8 aditivo haría el trabajo si solo desea detectar si algo ha cambiado y no espera otra cosa que eso del CRC).

Opción 2: más allá de los CRC: hacerlo con bastante rapidez mientras se mejora la detección de cambios:

Otras opciones válidas (ver el comentario de @ poncho ) son simplemente verificar la marca de tiempo del último mod .

O combina ambos (para evitar cuellos de botella), usando algo como este pseudocódigo muestra:

if(LastMod != knownLastMod) { CreateNewCRCandCompare(FileName, knownCRC) };

Pero, ¿ofrece esto alguna seguridad real? No. Lo mismo va para tu ...

Por qué considero que verificar la cola es:
- MP3 tiene la información de la etiqueta allí
- EXIF ​​agrega datos personalizados al final si tengo razón

Nuevamente, depende de cuánta seguridad espere. Tiene que darse cuenta de que un adversario seguramente manipulará el archivo para mantener (o copiar y pegar) cualquier información ID3 y EXIF ​​antigua ... ya que cualquiera (con los derechos de acceso a archivos RW apropiados) puede modificar eso. Lo mismo ocurre con la marca de tiempo de la última modificación, la velocidad de fotogramas, la resolución, la fecha del último cambio e incluso la longitud (del archivo). Dependiendo de que los datos "adicionales" y "modificables", que pueden ser modificados y eliminados por cualquier persona con suficientes derechos de acceso a los archivos, se introduciría una falla de seguridad.

Pero sí esperas seguridad, ¿no? Después de todo, esa es la razón por la que estás pensando en todo esto en primer lugar. Bueno, entonces no hay forma de evitar el uso de hashes cripto-seguros ...

Opción 3: hashes criptográficamente seguros: hacerlo de forma segura al precio de la velocidad:

Si espera seguridad real, tendrá que confiar en el hash; para ser más precisos: hashing criptográficamente seguro (usando un hash que no se sabe que produce colisiones). Lleva tiempo (unos microsecs por MB) pero vale la pena.

Mis 2 centavos (personales):

Trate de vivir con el hecho de que el hash cuesta tiempo y el hash de todos los archivos con un hash criptográficamente seguro . Porque, cuando las cosas comienzan a golpear al ventilador ... es mejor ser lento, en lugar de lamentar.

EDITAR en función de su EDITAR ...

Si la seguridad criptográfica no es su enfoque principal, puede mirar MD5 o SHA1. Tanto MD5 como SHA1 están "criptográficamente rotos" porque se han detectado colisiones ... sin embargo, para los fines de detección de cambios que describe (especialmente después de su EDIT), la probabilidad de golpear dicha colisión debería ser lo suficientemente mínima.

Mirando todo de nuevo (incluido su EDIT), lo más probable es que yo personalmente use MD5, ya que ofrece una resistencia a la colisión utilizable (para fines de detección de cambios) y al mismo tiempo es lo suficientemente rápido como para hash completamente archivos de varios gigabytes.

Si eso aún no lo satisface en un sentido de "velocidad" o si sus recursos de hardware son realmente tan limitados, debe intentar equilibrar la resistencia a colisiones / detección de cambios con la velocidad. Sentido…

Tome la marca de tiempo individual, el nombre de archivo individual y el encabezado hash (la longitud depende del tipo de medio y el formato de archivo utilizado), así como una buena porción del medio y una buena porción de la cola (= final del archivo). Combina esos 5 y deberías poder filtrar más o menos

Estaría bien con un ~ 80% de posibilidades de tener los marcadores correctos. ¿Cuántas piezas hash debo juntar y en qué parte del archivo estarían?

Esa es más una opinión personal, ya que depende de una gran cantidad de detalles (tipo de medio, formato de archivo, recursos disponibles, relación de detección de cambio esperada, similitud de archivo, etc.), por lo que tendrá que equilibrarlo usted mismo dependiendo de su personal expectativas, sus implementaciones y resultados locales debido a cuellos de botella de hardware y / o software.

No obstante, permítame intentar brindarle alguna orientación:

Si el hash del archivo completo no es una opción por alguna razón, tomaría, al menos, el encabezado (y tal vez algunos KB más), una buena porción del medio (al menos el tamaño del "encabezado y código" . ") Y una buena parte del final del archivo (de nuevo, al menos el tamaño de la parte" header & co. ").

Cuantos más recursos pueda invertir (o esté dispuesto a invertir), más trozos puede tomar y / o más grandes pueden ser esos trozos. Si crees que tus recursos / sensación / lo que sea que todavía ofrece espacio para más, aumenta el tamaño de los fragmentos que hash y / o aumenta el número de fragmentos que hash.

Aumentar la cantidad de fragmentos es fácil: ya que todo lo que necesita hacer es cuidar una distribución equitativa (dividiendo el tamaño del archivo en consecuencia, lo que resulta en fragmentos del mismo tamaño que extrae de partes equidistantes en toda la longitud del archivo).

Y si se está preguntando "¿Por qué distribuir partes de fragmentos equitativamente y no al azar?", Permítanme señalar que elegir posiciones de fragmentos aleatorios prácticamente podría anular sus esfuerzos de detección de cambios, ya que incorpora el riesgo de omitir algunos medios importantes donde normalmente detectaría las posibilidades que intenta detectar. Elegir una distribución igual es, simplemente dicho, más neutral.


1
No usaría CRC32, una gran posibilidad de falla incluso sin ataques maliciosos. Crypto es bastante rápido. Debe obtener 1 GB / s en un solo núcleo con un hash estándar. Si lo debilita un poco, 3GB / s debería ser posible. Es casi seguro que IO es más caro que el hashing.
CodesInChaos

@CodesInChaos Estoy de acuerdo. Es por eso que mis palabras de cierre recomiendan buscar un hash criptográficamente seguro.
e-sushi

1
Los hash de Carter-Wegman y otros hash universales podrían ayudar. Estos tienen la velocidad de un CRC amplio y la seguridad de los hashes, suponiendo que una clave permanezca desconocida para el atacante y no se reutilice. Ver esta respuesta para referencias.
fgrieu

@fgrieu ¿Pero eso no significaría, en la situación de los OP, que OP necesitaría una clave individual por archivo? Me parece poco práctico. Especialmente, ya que introduciría la necesidad de gestión de claves, etc., solo para verificar posibles modificaciones de archivos.
e-sushi

1
@ e-suschi: si hay algún identificador de archivo único (como una ruta), una clave maestra y HMAC es todo lo que se necesita para obtener una clave única por archivo. Dicho esto, si el adversario obtiene acceso de lectura a la clave, puede realizar una falsificación, cuando no puede hacerlo con un hash regular del archivo y acceso de solo lectura.
fgrieu

5

Atajos

Si tiene varios archivos y desea detectar cambios en los archivos, use el tamaño del archivo y la marca de tiempo de la última modificación.

Es posible que el sistema operativo que utiliza proporcione funciones para detectar cambios en los archivos, por ejemplo, Linux permite recibir notificaciones de cambios en los directorios.

Procesamiento completo de archivos

Si necesita leer el contenido real de los archivos para verificar si los archivos han cambiado, vaya con el hash criptográfico real. CRC tiene un potencial significativo de dar un falso negativo. SHA-256 puede ser bastante bueno, pero en realidad, SHA-512 es más rápido en muchas plataformas modernas.

Si tiene muchos núcleos de CPU, podría ser útil calcular diferentes hashes para diferentes partes del archivo o usar un árbol de hash para paralelizar el procesamiento.

La razón para sugerir un hash adecuado es que una vez que accede a los datos reales del archivo, el procesamiento criptográfico no será demasiado, en su lugar habrá muchas otras cosas más lentas, por ejemplo, E / S de disco o envío y recepción de paquetes de red.

Nota: Para (al menos) archivos pequeños, también es posible almacenar el contenido completo del archivo y hacer una comparación de los contenidos en lugar de hash.

Nota 2: Si tiene poco espacio de almacenamiento, CRC o hash criptográfico truncado podría ser una buena opción. CRC32 toma 4 bytes por archivo, y SHA-256 es de 32 bytes. Las etiquetas pequeñas de 4 bytes no pueden proteger contra intentos maliciosos de ocultar ediciones.

Procesamiento parcial de archivos

En la mayoría de los casos, recomendaría usar solo el procesamiento completo de archivos.

Tal vez es más una pregunta matemática ahora, pero: ¿qué tan probable es detectar un cambio usando la combinación de tamaño de archivo, encabezado, cola y datos aleatorios para generar esta suma rápida de hash?

Para los archivos de imagen, es común hacer pequeñas ediciones, como eliminar ojos rojos, agregar bigote o cuernos, etc. Estas ediciones en formato JPG ocasionalmente no afectarían el tamaño del archivo (con el programa de edición que puede hacer cambios a JPG con la recompresión solo alterada áreas) o uno de los otros atributos que menciona.

Sin embargo, el tiempo de modificación del archivo generalmente se vería afectado.

Considerando los archivos de video: muchos formatos de video generan una tasa de bits constante. Para el archivo de velocidad de bits constante, si se alteran algunos cuadros en el medio, tampoco aparecerá en el tamaño del archivo, la cabeza o la cola. Eliminar o agregar marcos casi siempre resultará en una diferencia de tamaño.

Por lo tanto, veo que es posible que el campo obtenga cambios sin que se detecte.

Es muy difícil estimar las ediciones de probabilidad que se detectan con este esquema, pero hay escenarios de uso comunes para videos e imágenes que no se detectan correctamente.


Sí, las pequeñas ediciones en archivos PNG o WAV tienen una gran posibilidad de perderse si solo se procesan algunos fragmentos.
galinette
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.