Al leer varias de estas respuestas, creo que podrían no tener sentido a menos que ya esté bien versado en la terminología relevante, así que permítame tratar de explicar esto de una manera que tenga más sentido para los no iniciados.
Un hash, como muchos han dicho, está destinado a ser una función unidireccional. Más importante aún, un hash asigna de un conjunto de cosas a un rango conocido. Por ejemplo, un hash se puede usar para convertir cualquier cadena en un número entre 0 y 4 millones.
Antes de llegar demasiado lejos, hablemos de las funciones unidireccionales y bidireccionales. ( Editar: Permítanme aclarar que no estoy usando las definiciones matemáticas o criptográficas formales; estoy comenzando con definiciones con sentido común para que sea más fácil pensar en ellas; al final de mi respuesta, insinuaré las propiedades de definiciones formales ) . Crear una función trivial unidireccional es fácil. Por ejemplo, f(x) = 0
es una función trivial unidireccional. Su salida es SIEMPRE 0, por lo que es imposible saber cuál fue la entrada de esa función basada en la salida. Lo contrario de una función unidireccional es una función bidireccional, como f(x) = x*2
. Esa es una función bidireccional, porque puede calcular la entrada en función de la salida simplemente dividiendo la salida por dos.
Las funciones de hash son mucho más complicadas que f(x)=0
(naturalmente), entonces, ¿cómo sabemos que son irreversibles? Bueno, depende de lo que quieras decir con irreversible.
Como dije, las funciones hash se asignan de un conjunto de entradas a otro conjunto de salidas. Normalmente, el tamaño del conjunto de salida es menor que el tamaño del conjunto de entrada. Por ejemplo, tome el venerable algoritmo de hash MD5. Asigna un conjunto de entradas (el conjunto de todas las secuencias de bytes, de cualquier longitud) a un conjunto de salidas (el conjunto de todos los números enteros (también conocidos como enteros) de 0 a 2 ^ 128). Ahora, ese conjunto de resultados es enorme . Escrito en formato largo, eso es 340,282,366,920,938,463,463,374,607,431,768,211,456 valores posibles. Afortunadamente, podemos representar cualquier número en ese conjunto con 128 bits (es decir, 16 bytes). Pero el conjunto de posibles entradas es aún mayor. Esencialmente, el conjunto de posibles entradas es infinito. Literalmente, no hay límite para el número de combinaciones de CUALQUIER número de bytes. Lo que eso significa, naturalmente, es que cada valor posible en ese rango (0 a 2 ^ 128) puede ser generado por múltiples entradas posibles. Si ha escrito bien su función hash, entonces cada valor posible en la salida podría generarse por un número infinito de entradas diferentes.
Literalmente, si el hash MD5 fuera perfectamente reversible, eso significaría algo sorprendente: significaría que solo hay 2 ^ 128 cosas posibles en el universo. Significaría que cualquier cosa y todo podría ser “comprimido” hasta 16 bytes; referido perfectamente por su identificador de 16 bits. Como ese no es el caso, el hash MD5 es, en ese sentido, una función irreversible o unidireccional.
Pero espera. Digamos que inventamos una función hash (la llamaremos ‘stupidHash’) que tomó cualquier entrada dada, representada como un número (es decir, cualquier secuencia de cualquier número de bytes), dividió esa entrada por 10 y devolvió el resto. El resto está garantizado para estar en el rango de 0 a 9 (inclusive). Entonces: ¿hemos creado una función unidireccional? Bueno, un poco, pero depende de cómo se defina “unidireccional”. Dada una salida (por ejemplo, 5) no puedo saber qué entrada le dio a esa función para generar esa salida (tal vez su entrada fue 35 o 155, ¿cómo podría saberlo?) … pero PUEDO encontrar fácilmente una entrada que usted PODRÍA dar el stupidHash que también generaría esa misma salida. ¿Es eso lo mismo que una función bidireccional? No exactamente … pero está lo suficientemente cerca como para el propósito de una “función unidireccional”, lo que hace que no sea unidireccional según la definición formal.
¿Por qué nos importa? Bueno, la cosa es que una de las cosas comunes que se deben hacer en las computadoras para evitar almacenar su contraseña es almacenar un hash de su contraseña. Esto es bastante inteligente, porque significa que la computadora no tiene que almacenar su contraseña, pero aún puede verificar cualquier contraseña de entrada para asegurarse de que sea la contraseña correcta. Cualquier contraseña de entrada se convertirá en hash, en comparación con el hash almacenado, y si los dos hashes coinciden, ¡esa debe ser la contraseña correcta! Incluso si un hacker logra robar el hash, el hacker aún no conoce su contraseña. Brillante, ¿verdad? ¡Pero espera! El hacker no NECESITA su contraseña exacta. Solo necesita algo que tenga el mismo valor. A veces, esa cosa que generará el hash con el mismo valor se denomina “pseudoinverso” del valor de hash.
Aquí es donde nos encontramos con respecto a la definición moderna (criptográfica) de “reversible”: si te digo el valor hash, ¿puedes averiguar alguna entrada que puedas dar a la función hash que generará ese mismo valor de salida? Si es así, la función se considera “reversible”, incluso si la otra cosa que le das no se parece en nada a la entrada original.
Para las funciones unidireccionales criptográficas fuertes, es realmente difícil hacerlo. No es imposible, de ninguna manera, pero REALMENTE difícil. La cuestión es que las personas se han vuelto muy buenas para descubrir formas inteligentes de almacenar valores parcialmente hash y facilitar el problema (este es el problema con el que se encontró MD5; es una técnica conocida como “tablas de arco iris”). Pero para funciones hash realmente bien escritas, eso requiere una cantidad astronómica de almacenamiento o una cantidad astronómica de potencia de cálculo (y a veces ambas).
Como han señalado otros, no hay pruebas de que las funciones unidireccionales sean verdaderamente unidireccionales (basadas en la definición bastante específica de unidireccional que se utiliza; consulte Wikipedia para obtener detalles matemáticos sangrientos), pero HEMOS demostrado que si existe una función unidireccional, eso significa que hay dos clases de problemas fundamentalmente diferentes: difícil (P) y loco-duro (NP). En otras palabras, si pudiéramos demostrar que un hash no trivial no se puede revertir (o seudo-revertir), entonces habríamos resuelto el mayor enigma teórico en toda la informática.