¿Por qué no puede obtener una contraseña real del valor hash mientras se descifra la contraseña?

Dos razones principales por las que no puede revertir un algoritmo hash (o incluso mejor un algoritmo hash criptográfico):

1.) Los algoritmos de hash están construidos con funciones unidireccionales diseñadas para ser computacionalmente inviables de revertir. Lo que quiero decir con esto es que, si bien siempre van a surgir colisiones (dada una salida lo suficientemente pequeña y una entrada lo suficientemente grande, vea la respuesta de Miguel Paraz), los buenos algoritmos de hash criptográficos se diseñan utilizando algoritmos que se sabe que son computacionalmente difíciles retroceder.

Un buen ejemplo de una función unidireccional es la siguiente:
X = h (n, q) = n * q.

Dado X, es computacionalmente difícil buscar el par n * q. Tendría que buscar el producto de un par de números hasta X, un problema O (X ^ 2). Si X es lo suficientemente grande, básicamente estás jodido (este es un ejemplo del problema de factorización del producto: ver Función unidireccional)

Los hash criptográficos de la vida real son mucho más complicados que esto, y usan otros trucos para obligar a los criptoanalistas a abordar problemas no resueltos en matemáticas como el problema del logaritmo discreto.

2.) Las sales se usan con frecuencia para complicar aún más la inversión de los hashes. Las buenas estructuras de hash, como las que se usan para almacenar contraseñas, con frecuencia emplean sales para hacer que la reversión de sus funciones internas de un solo sentido sea aún más complicada.

Una sal es un dato que se agrega a la entrada de un hash. Complica el problema de revertir el hash porque incluso la fuerza bruta que fuerza la entrada a través del algoritmo no necesariamente devolverá el mismo resultado.

Por ejemplo, supongamos que agrego una “sal” constante seleccionada al azar en mi algoritmo de hashing anterior. Mi nuevo algoritmo es el siguiente:

X = h (n, q) = n * q * sal.

Incluso si tengo suerte y encuentro n y Q, ahora necesito encontrar “sal” o esperar que el algoritmo seleccione la misma constante que obtuve cuando se creó X por primera vez.

También puede agregar un elemento temporal a esta estructura haciendo que la generación de su sal sea una función del tiempo o el lugar (es decir, cuando se generó el hash). Con frecuencia, esto se emplea sembrando un generador de números pseudoaleatorio con datos temporales o basados ​​en la ubicación geográfica, como qué hora es, dónde se encontraba la computadora que generó el hash en el mundo o alguna combinación de los dos.

De esta forma, necesitaría recopilar mucha más información sobre cómo se creó el hash y cuándo se creó antes de lanzarlo en el camino de romper la función unidireccional.

Una respuesta simple:

Porque los hashes son resúmenes. Toman una gran cantidad de datos y la resumen en una pequeña cantidad de bits. Para MD4, esto es 128 bits. Estos 128 bits no se pueden volver a cambiar al tamaño original.

Debido a esto, es posible tener múltiples valores hash de múltiples contraseñas diferentes, pero la probabilidad es pequeña.

Las funciones hash funcionan incluso si la entrada es más pequeña que la salida. Incluso un solo byte puede tener un hash completo de 128 bits. Esta es la razón por la cual las contraseñas de menos de 16 bytes (o 16 caracteres) se pueden cifrar.

Tener el mismo valor de hash de múltiples contraseñas se llama “colisión de hash”. Esto es algo que todos los algoritmos de hash se esfuerzan por evitar, y los modernos han logrado ser muy buenos.

La razón por la que no podemos revertir el hash es que implican decisiones lógicas que no son fáciles de revertir. Los hash reales son bastante complicados, pero una ilustración del concepto se puede encontrar en Minecraft.

Minecraft puede generar un mundo basado en un valor de semilla corto: la semilla “01234ABCD” siempre generará el mismo mundo, siempre. “01234ABCC” genera un mundo muy diferente, sin patrones comunes excepto ruido aleatorio coincidente. Ahora, imagine que crea un mundo a partir de un valor semilla, luego mire cada bloque en una lista de 64 coordenadas predeterminadas y registre lo que encuentre. Entonces, en (3, 1, 44), tienes un bloque de Dirt, D. En (170, 9, 33), tienes un bloque de Carbón, C. Terminas con un código único de 64 caracteres.

Si conoce el código de 64 caracteres, le resultará increíblemente difícil averiguar el valor inicial de la semilla: no hay nada que se asigne desde los bloques a los valores iniciales. Si tiene el valor inicial, puede generar el mundo y obtener ese código de 64 caracteres cada vez. Los hashes funcionan según un principio muy similar.

El hash es solo eso … un hash. No contiene suficiente información.

Mira esta fórmula …

X = 4

Y =?

X + Y = 6

A partir de eso, puede decir que y es 4. SIN EMBARGO, elimine cualquiera de los otros dos números y no podrá.

X =?
Y =?
X + Y = 6

¿Qué es y? Podría ser cualquier cosa.

X en lo anterior es como la sal en el hash. El hash es una operación que, combinada con la sal, produce un número.

Sin embargo, no solo no se conoce la sal, sino que, de hecho, diferentes contraseñas con la misma sal pueden producir el mismo hash.

Considere esta operación:

X = 4
Y =?

Y% X = 2

Incluso si conoce la sal, hay un número infinito de valores Y que se pueden modificar contra X para producir 2. Por lo tanto, conocer la sal no es suficiente para aplicar ingeniería inversa a la contraseña, solo reduce el posible campo de valores (en este caso , un infinito menor pero eso es porque, a diferencia de los números en una computadora, los números en el mundo real son infinitos).

El mod es un ejemplo de un hash muy muy simplista.

Por lo tanto, el hash se puede volver a calcular teniendo en cuenta la sal y la contraseña, que es lo que se hace cuando una contraseña enviada se compara con el hash almacenado, pero la contraseña no se puede encontrar hacia atrás desde el hash.

* Una * contraseña de trabajo (sin embargo, no se puede encontrar la misma) si se conoce la sal Por eso es un secreto.

¿Eso tiene más sentido?