¿Hashing criptográfico sin colisiones?

2

Deseo hacer un hash de algo que genere un hash sin colisiones, y usar ese hash como un id en una base de datos. El uso del hash criptográfico convencional (longitud fija) significa que existe una posibilidad de colisión y que la identificación podría no ser única.

¿Existe tal hash criptográfico?

Supongo que siempre podría usar el cifrado asimétrico determinista y cifrar algo con la clave pública, descartar la clave privada y usar la salida como una especie de hash, pero de todos modos, me preguntaba si hay otras posibilidades. p>

Básicamente, mi problema es este: quiero que cada nombre de usuario tenga un registro en mi base de datos, pero si alguien obtiene una retención de mi base de datos, no quiero que nadie pueda leer el nombre de usuario de un registro. Ningún usuario sabrá nunca el nombre de usuario de otra persona, eliminando así la posibilidad de simplemente modificar y probar si alguien existe en la base de datos.

    
pregunta HelloWorld 07.05.2018 - 01:14
fuente

1 respuesta

4

Lo que estás pidiendo es un random oracle , un hash ideal hipotético eso no puede crear colisiones a menos que la entrada sea más grande que la salida. Tal hash no existe en la realidad, y lo mejor que puede obtener son los hash criptográficos actuales que hacen que sea más difícil encontrar colisiones intencionalmente. Cuanto mayor sea la salida del hash, menor será la posibilidad de una colisión involuntaria. Es improbable que un hash fuerte como SHA-256 alguna vez , incluso si estuvieras generando intencionalmente miles de millones de ID por segundo.

La posibilidad de una colisión es 1 - e -b (b - 1) / 2n , donde n es el número de distintos Los ID en su conjunto y b es el número de bits en el resumen de hash. Este sitio web explica más acerca de los riesgos de colisión de hash.

Si todo lo que quieres hacer es generar una ID única pseudoaleatoria dada una entrada de tamaño fijo, puedes usar un cifrado de bloque. La entrada es el ID de entrada y la salida es el ID único, pseudoaleatorio. Esto se puede describir como H = E k (ID) , y es similar a un cifrado de bloque en el modo de contador. Mientras que la entrada y la salida solo tengan que ser tan grandes como el tamaño del bloque, no habrá colisiones. Tenga en cuenta que, a diferencia de un hash, esto es reversible y el conocimiento de la clave puede utilizarse para calcular la ID original.

El tamaño de bloque del cifrado es lo que determina los tamaños de entrada y salida. Por ejemplo, un cifrado de bloque de 64 bits requiere una ID de 64 bits como entrada y generará un valor de 64 bits que se puede usar en lugar de su hash. Cada entrada de 64 bits distinta se asignará a una salida de 64 bits distinta y pseudoaleatoria. La entrada puede ser más pequeña que el tamaño del bloque si se rellena con un valor constante, pero la salida se debe usar como está. Si se trunca la entrada o la salida, existe el riesgo de que se produzcan colisiones.

El uso de un cifrado de bloque puede no ser práctico si está convirtiendo los nombres de usuario en ID, porque un tamaño de bloque de 64 bits (por ejemplo) puede aceptar como máximo un nombre de usuario de 8 caracteres, asuming ASCII . Si la entrada tiene que ser de tamaño variable, le insto a que use una función hash. La posibilidad de colisiones para un hash fuerte de ≥160 bits es vandamente pequeña. Para esto están diseñados los hashes.

    
respondido por el forest 07.05.2018 - 01:15
fuente

Lea otras preguntas en las etiquetas