El protocolo es en realidad como [datos, HMAC-SHA1 (datos)] (o con otro hash en lugar de SHA-1). Lo que se necesita aquí es autenticar los datos, es decir, garantizar que provengan de una fuente que conozca una clave secreta en particular. Un hash permite al destinatario comprobar que los datos son iguales a otra cosa, pero el destinatario no tiene nada con qué comparar. En contraste, un MAC permite al destinatario verificar que fue generado por una entidad que conoce la clave secreta.
Estás intentando construir un MAC sobre un cifrado de bloque. Esto es posible, pero lo estás haciendo mal. Supongamos, mientras lo hace, que los datos están cifrados con un cifrado de bloque en modo CBC.
Los datos y la suma de comprobación en sí están cifrados, y cualquier pequeño cambio en los datos cifrados cambiaría al menos un bloque completo (de forma impredecible por un posible atacante).
Eso es cierto: un bloque cambia de forma impredecible. Sin embargo, esto no es lo suficientemente bueno: necesita ver las consecuencias en los otros bloques.
Debido al modo de cifrado (CBC) y al hecho de que el hash se almacena al final del paquete, supongo que incluso el hash cambiaría de forma impredecible.
No, el hash no cambiaría de forma impredecible si el atacante tiene cuidado. De hecho, es bastante fácil evitar cambiar el hash que eligió, que es el XOR de todos los bloques. CBC usa XOR internamente, por lo que esto no debería ser una sorpresa completa.
Considere un mensaje que consta de tres bloques P₁
, P₂
, P₃
y la suma de comprobación P₊
cifrada con CBC, y deje que C₁
, C₂
, C₃
, C₊
sea el texto cifrado correspondiente. Escribiré E
para la función de cifrado de bloque y D
para el descifrado.
C₁ = E(P₁ ⊕ IV)
C₂ = E(P₂ ⊕ C₁)
C₃ = E(P₃ ⊕ C₂)
C₊ = E(P₊ ⊕ C₃) where P₊ = P₁ ⊕ P₂ ⊕ P₃
El lado receptor se descifra con
P₁ = D(C₁) ⊕ IV
P₂ = D(C₂) ⊕ C₁
P₃ = D(C₃) ⊕ C₂
P₊ = D(C₊) ⊕ C₃
Un atacante de hombre en el medio invierte C₁
y C₂
. Esto es lo que ve el destinatario:
P₁' = D(C₂) ⊕ IV
P₂' = D(C₁) ⊕ C₂
P₃' = D(C₃) ⊕ C₁
P₊' = D(C₊) ⊕ C₃
Note que P₊' = P₊
- perturbar un texto cifrado CBC solo tiene un efecto hasta el siguiente bloque después de la perturbación, el resto permanece intacto. Y
P₁' ⊕ P₂' ⊕ P₃' = D(C₂) ⊕ IV ⊕ D(C₁) ⊕ C₂ ⊕ D(C₃) ⊕ C₁
P₁ ⊕ P₂ ⊕ P₃ = D(C₁) ⊕ IV ⊕ D(C₂) ⊕ C₁ ⊕ D(C₃) ⊕ C₂
Oh, mira, estos son los mismos. La suma de comprobación en el mensaje modificado es correcta.
Es posible diseñar un algoritmo MAC basado en CBC, pero debes tener más cuidado que esto. Un CBC-MAC ingenuo permite ataques del tipo que notó, jugando con la longitud. Hay variantes que no tienen este problema. Sin embargo, hay un inconveniente: ¡no debe usar la misma clave para el cifrado CBC y CBC-MAC! Esto se debe a que si usa la misma clave y el atacante tiene control sobre parte del texto sin formato, entonces el atacante puede hacer que el remitente calcule un MAC para ella. Por ejemplo, el CBC-MAC de un mensaje de un bloque es solo el resultado de cifrar ese bloque. Entonces, si el atacante desea enviar un mensaje de un solo bloque, todo lo que tienen que hacer es organizar que el remitente encripte un mensaje que comience con ese bloque y lea el resultado. Es un principio general que usar la misma clave para dos cosas diferentes es peligroso porque permite errores de confusión de protocolo cuando el mismo cálculo produce datos que deben ser públicos para uno de los usos de la clave y privados para el otro uso.
Xor es no tan bueno como un MAC. De hecho, incluso su lectura inicial de la etiqueta de autenticación como [datos, SHA1 (datos)] no funcionaría, porque el cifrado CBC de un hash no es seguro (la falla es más sutil que con xor, pero existe).