La forma más sencilla de comprender MD5 es implementarlo a partir de la especificación , que es bastante simple.
En palabras muy crudas:
-
Los datos de hash son una secuencia de bits. Mantengamos las cosas simples y supongamos que es una secuencia de bytes . Se añaden unos pocos bytes adicionales (el "relleno") a esa secuencia, de modo que el número de bytes adicionales está entre 9 y 72 (inclusive) y la longitud total después del relleno es un múltiplo de 64. La especificación explica el contenido de la relleno; básicamente muchos ceros y una codificación de la longitud de los datos de entrada.
-
Los datos rellenados se dividen en bloques de 64 bytes. Los bloques serán procesados uno por uno. El procesamiento de cada bloque (64 bytes) toma como entrada un valor de 128 bits (16 bytes) que es la salida del procesamiento del bloque anterior, y genera un nuevo valor de 128 bits.
-
Como el primer bloque no tiene un bloque anterior, se utiliza un valor fijo convencional para iniciar el proceso. La especificación MD5 detalla ese valor.
-
La salida MD5 completa es el valor de 128 bits que se obtiene después de procesar el último bloque.
El procesamiento de un solo bloque divide el valor de 128 bits obtenido del bloque anterior y el nuevo bloque a procesar, en palabras de 32 bits (4 palabras para el valor anterior, 16 palabras para el bloque). Todos los cálculos se realizan con estas palabras de 32 bits. La estructura general se ha descrito como un algoritmo de cifrado que se encuentra de lado: el bloque de 64 bytes se utiliza como una especie de clave para cifrar el estado de ejecución de 128 bits, en un esquema generalizado de Feistel. Soy consciente de que tal afirmación no explica realmente las cosas, para realmente entender lo que está sucediendo en el algoritmo, usar su lenguaje de programación favorito e intentar implementarlo.
(Cualquier lenguaje debería estar bien para una tarea de este tipo, ya que solo se trata de aprender, pero algunos son menos buenos que otros. Por ejemplo, los números de Javascript son realmente valores de punto flotante, lo cual es incómodo para implementar MD5. Java y C # son buenas para tales tareas, especialmente porque tienen tipos de enteros con una longitud garantizada de 32 bits, exactamente lo que necesita para MD5.)
También es posible que desee leer esta respuesta , que trata de explicar por qué las funciones hash son "unidireccionales". ", y toma MD5 como ejemplo, por lo que incluye una descripción de MD5.