El MAC está allí para detectar la alteración de los datos en los que está interesado, es decir, el resultado del descifrado. Así que tienes la siguiente opción:
- o bien calcula HMAC sobre los datos de texto sin formato (es decir, antes del cifrado al cifrar, después del descifrado al descifrar);
- o calcula el HMAC sobre los datos encriptados (es decir, después del cifrado al cifrar, antes del descifrado al descifrar).
En el segundo caso, debe incluir en la entrada HMAC todo que afecte el proceso de descifrado, es decir, no solo el resultado del cifrado en sí, sino también el IV que se utilizó para ese cifrado. y, si el protocolo general admite la agilidad del algoritmo, también debe ingresar la especificación del algoritmo de cifrado (de lo contrario, un atacante podría alterar el encabezado de su mensaje para reemplazar la etiqueta que dice "AES-256" con la etiqueta que dice "AES -128 "y, sin saberlo, descifrarías con el algoritmo incorrecto).
Para seguridad , la segunda opción (cifrar luego MAC) es mejor; vea esta pregunta en crypto.SE para detalles (para resumir, cuando el MAC se calcula sobre los datos encriptados, no puede filtrar información sobre los datos de texto sin formato y, como se verifica antes de intentar descifrar, protege contra los ataques de texto cifrado seleccionados). SSL usa MAC-then-encrypt y ha sido el origen de muchos problemas (todos los "ataques oracle de relleno" y también el llamado ataque BEAST se hubieran evitado con cifrar y luego MAC).
En cuanto a las claves, idealmente, la clave de cifrado y la clave MAC deben derivarse de una clave maestra con una PRF . En palabras sencillas: hash tu clave maestra K con SHA-512; La primera mitad del resultado será la clave de cifrado, la segunda mitad será la clave para HMAC.
Pero, realmente, debe utilizar EAX o GCM . Hacen todo correctamente y (eso es un punto importante) tienen requisitos muy ligeros en la selección IV: solo necesitan un IV no repetitivo, por lo tanto, pueden usar un contador simple, mientras que el CTR hecho a mano necesita rangos IV no superpuestos rangos (una IV con selección aleatoria uniforme es correcta, pero la aleatoriedad es un requisito difícil) (y CBC es aún peor, necesita aleatoriedad impredecible ). La única justificación para no usar EAX o GCM en un sistema nuevo (donde no está limitado por la compatibilidad con versiones anteriores) es una posible no disponibilidad de una implementación de EAX o GCM. Yo diría que, incluso en este caso, sería mejor adaptar un código AES-ECB a una implementación de EAX.