8.15. Métodos de verificación de integridad

 

8.15.1. HMAC (Hashing for Message Authentication Codes) [RFC-2104]

Para proveer un modo de chequear integridad de la información transmitida o almacenada en un medio no confiable es necesario un mecanismo que permita compararla contra algo que se considere válido. Para esto se estandarizó un procedimiento basado en una clave secreta usualmente llamado Código de Autenticación de Mensajes (MAC). El empleo típico de estos mecanismos es a través de dos partes que comparten una clave secreta para validar la información transmitida entre ellas. HMAC propone el empleo de criptografía aplicada a funciones Hash (resúmenes). En la RFC, estandariza el empleo de HMAC con las funciones Hash definidas como MD5 (Message Digest versión 5) [RFC-1321] y SHA-1 (Standard Hash Algorithm Versión 1) [FIPS 180-1]. También hace mención al algoritmo propuesto por RIPE denominado RIPEMD-128/160.

HMAC requiere una función Hash (H) que se encargará de comprimir un texto de longitud finita por medio de iteraciones de una función de compresión básica sobre los bloques de datos (B = 64 Byte), y una clave secreta (K); y por medio de ambas se obtendrá un resumen de longitud fija (L), que será de 16 Byte para MD5 y 20 Byte para SHA-1.

Esta función Hash es llamada "One Way" pues no es posible a través del resumen de salida obtener el texto de entrada, también resultará computacionalmente imposible obtener un valor de salida igual a través de otro valor de entrada, como así tampoco desde un valor de salida ya calculado, obtener otro valor de entrada diferente al verdadero.

Se definen dos cadenas de longitud fija diferentes una de la otra llamadas:

Ipad = repetición del Byte 36 B veces.

Opad = repetición del Byte 5C B veces.

Luego se ejecuta: H { KB xor Opad, H (KB xor Ipad, texto)}

Para esta tarea se debe tener en cuenta:

  1. Rellenar con ceros la clave K hasta obtener una longitud de 64 Byte (llamada KB).
  2. Realizar: KB xor Ipad , (Result1).
  3. Anexar el texto completo al resultado de b, (Result2).
  4. Aplicar la función Hash (H) al resultado de c, (Result3).
  5. Realizar: KB xor Opad, (Result4).
  6. Anexar el resultado de d, (Result3). Al resultado de e, (Result4).
  7. Aplicar la función Hash (H) al resultado de f. Obteniendo el resultado, que acorde a la función Hash empleada será de 16 o 20 Byte.

Se hace especial hincapié en la elección de la clave a través de un algoritmo pseudoaleatorio verificado y que no presente vulnerabilidades, si bien no se especifica ninguno en particular.

 

Esquema:

 

.

8.15.2. The MD5 Message-Digest Algorithm [RFC-1321].

Este algoritmo toma un mensaje de entrada de longitud arbitraria y entrega una salida de 128 bit de longitud fija. Llamado "Huella digital" o "Recopilación de mensaje (Message Digest). Es computacionalmente imposible producir dos mensajes que posean la misma recopilación, como tampoco regenerar el mensaje a través de la recopilación. Este algoritmo puede ser empleado para aplicaciones de firma digital, donde un texto debe ser comprimido de manera segura antes de ser encriptado con sistemas de clave privada.

El algoritmo MD5:

Se implementa por medio de 5 pasos:

Paso 1: Anexa bit de relleno.

Se anexan bit de relleno para que el mensaje dividido 512 tenga resto 448, es decir 448 (mod 512). El primer bit de relleno será un uno y luego se continuará con una cadena de ceros.

Paso 2: Anexa longitud.

Una representación de 64 bit del mensaje original (antes del paso 1) es anexada al resultado. En este paso el mensaje resultante es un múltiplo exacto de 512 bits, es decir que es múltiplo exacto de 16 palabras de longitud 32 bit.

Paso 3: Inicialización del buffer MD.

Un buffer de cuatro palabras (A, B, C, D) es empleado para procesar el mensaje generado luego del paso 2. Cada uno de estos buffer es un registro de 32 bit. Esos registros son inicializados con los siguientes valores en hexadecimal:

A: 01 23 45 67

B: 89 ab cd ef

C: fe dc ba 98

D: 76 54 32 10

Paso 4: Procesar el mensaje en bloques de 16 bit.

Se definen cuatro funciones auxiliares donde cada una tiene una entrada de tres palabras de 32 bit y produce una palabra de salida de 32 bit. Las funciones son:

F(X,Y,Z) = X.Y OR not(X).Z

G(X,Y,Z) = X.Z OR Y.not(Z)

F(X,Y,Z) = X XOR Y XOR Z

I(X,Y,Z) = Y XOR (X OR not(Z))

Como ejemplo de la función F, su tabla es:

X

Y

Z

F

0

0

0

0

0

0

1

1

0

1

0

0

0

1

1

1

1

0

0

0

1

0

1

0

1

1

0

1

1

1

1

1

Se procesa cada bloque de 32 bit bajo una serie de operaciones tabuladas en esta RFC [pág 5] y queda como resultado un valor de 32 bit en cada uno de los buffer A, B, C y D.

Se repiten los pasos a través de asignaciones de variables temporales (AA, BB, CC, DD) hasta el último bloque de texto, repitiendo sucesivamente la asignación que se detalla a continuación.

A = A + AA

B = B + BB

C = C + CC

D = D + DD

Al finalizar todos los ciclos (recordar que el texto de entrada es múltiplo exacto de 16 palabras de longitud 32 bit) quedan en los buffer A, B, C y D el resultado final del proceso.

 

Paso 5: Salida.

El mensaje generado es una salida de los Buffer A, B, C y D, los cuales se anexan desde el bit de menor orden de A hasta el último de D, por lo tanto esta salida es un mensaje de 128 bit de longitud.