2008-10-07 40 views
5

¿Hay alguna forma de generar un hash de una cadena para que el hash en sí tenga una longitud específica? Tengo una función que genera hashes de 41 bytes (SHA-1), pero necesito que sea de 33 bytes como máximo (debido a ciertas limitaciones de hardware). Si trunco ​​el hash de 41 bytes a 33, probablemente (¡ciertamente!) Perdí la singularidad.Hash de una cadena de longitud específica

O en realidad, supongo que un algoritmo MD5 podría encajar muy bien, si pudiera encontrar algún código C para uno con su ayuda.

EDIT: Gracias a todos por las respuestas rápidas y bien informadas. He elegido ir con un hash MD5 y me queda bien para mi propósito. La singularidad es un tema importante, pero no espero que la cantidad de hashes sea muy grande en un momento dado; estos hashes representan servidores de software en una LAN doméstica, por lo que al máximo habría 5, tal vez 10 en ejecución.

Respuesta

5

Se calcula el camino hash que desafortunadamente no es posible. Para limitar la longitud de hash a 33 bytes, tendrá que cortarla. Podría xor los primeros y últimos 33 bytes, ya que eso podría mantener más información. Pero incluso con 33 bytes, no tienes una gran posibilidad de colisión.

md5: http://www.md5hashing.com/c++/

por cierto. md5 tiene 16 bytes, sha1 20 bytes y sha256 tiene 32 bytes, sin embargo, como cadenas hexadecimales, todos duplican su tamaño. Si puedes almacenar bytes, incluso puedes usar sha256.

+0

Gracias, lo intentaré ... – dennisV

+1

Su BTW es la verdadera respuesta. Si le falta la memoria, ¡no almacene sus hashes como cadenas hexagonales! –

+0

md5 es 'más roto' que SHA1 y sha256. Sería mejor truncar y usar los 12 bytes adicionales de entropía. – Aaron

1

Creo que el algoritmo de hash MD5 da como resultado un número de 32 dígitos, por lo que quizás ese sea el más adecuado.

Editar: para acceder a la funcionalidad de MD5, debería ser posible enganchar en las bibliotecas de openssl. Sin embargo, usted mencionó las limitaciones de hardware, por lo que es posible que esto no sea posible en su caso.

+0

tu edición venció mi respuesta :) –

+0

Sí :) ¿Sabrías por casualidad dónde podría encontrar algún código para eso? ¡Gracias! – dennisV

+0

parece que Staale me ganó a ese –

3

Puede usar un Elf hash (< - código C incluido) o alguna otra función hash simple como esa en lugar de MD5 o SHA-X. Ellos no son seguras, pero pueden ser sintonizados a cualquier longitud que necesita

1

La posibilidad de una colisión de 33 bytes es 1/2^132 (por la paradoja del cumpleaños)

Así que no se preocupe por perdiendo la unicidad

Actualización: No verifiqué la longitud del byte real de SHA1. Aquí está el cálculo relevante: una colisión de 32 nibble (33 bytes de hex: 1 char de terminación) ocurre solo cuando el número de cadenas se convierte en hash sqrt (2^(32 * 4)) = 2^64.

2

hashes son, por definición, solamente es único para la pequeña cantidad de datos (e incluso entonces todavía no está garantizada). Es imposible asignar una gran cantidad de información de forma exclusiva a una pequeña cantidad de información en virtud del hecho de que no se puede eliminar mágicamente la información y recuperarla más tarde. Tenga en cuenta que esto no está pasando compresión.

Personalmente, usaría MD5 (si necesita almacenar en texto), o un hash 256b (32B) como SHA256 (si puede almacenar en binario) en esta situación. Truncar otro algoritmo hash a 33B también funciona, y PUEDE aumentar la posibilidad de generar colisiones hash. Depende mucho del algoritmo.

Also, yet another C implementation of MD5, by the people who designed it.

4

No hay más probabilidades de colisión con subcadena (sha_hash, 0, 33) que con cualquier otro hash que es de 33 bytes de longitud, debido a la forma algoritmos hash están diseñados (entropía está uniformemente disperso en la cadena resultante).

+2

Esto no es del todo cierto debido a la forma en que se calculan los hashes. Las matemáticas involucradas son complicadas, pero las colisiones parciales son mucho más fáciles de generar que las colisiones completas. –

+0

monóxido: Sí, son más fáciles en proporción a la cantidad de bits. 16 bytes de SHA1 es al menos tan seguro como un MD5. Si no fuera así, los hashes no serían seguros. –

+0

1/2 SHA1 realmente se consideraría más seguro en este momento. MD5 está 'roto' más que SHA1 – Aaron

6

Si trunco ​​el hash de 41 bytes a 33, es probable que (¡ciertamente!) Haya perdido la singularidad.

¿Qué te hace pensar que tienes unicidad ahora? Sí, claramente hay una mayor probabilidad de colisión cuando solo juegas con 33 bytes en lugar de 41, pero debes ser plenamente consciente de que las colisiones son poco probables, no imposibles, para cualquier situación en la que tenga sentido usar un hash. en primer lugar. Si está almacenando más de 41 bytes de datos, hay claramente más combinaciones posibles que hashes disponibles.

Ahora, ya sea que sea mejor truncar el hash SHA-1 o utilizar un hash más corto como MD5, no lo sé. Creo que sería más seguro en general al mantener el hash completo, pero MD5 tiene known vulnerabilities, lo que puede o no ser un problema para su aplicación en particular.

+0

No es tanto que tenga vulnerabilidades, sino que es que la informática ha avanzado hasta el punto en que el uso de la fuerza bruta ahora es práctico con las herramientas adecuadas. Con las precauciones adecuadas, MD5 es más o menos seguro. (lee: anteponer una sal) –

+0

Truncar un hash no le garantiza su unicidad y, por lo tanto, debe evitarse. –

+0

Andreas: Ya no tienes garantía de exclusividad. Es un hash, está haciendo un "gran esfuerzo" para llegar a la unicidad, pero fundamentalmente siempre debes considerar que los hashes no son únicos. –

Cuestiones relacionadas