Genera las 11 claves de ronda de AES-128 a partir de 16 bytes, descifra deshaciendo cada operación en orden inverso y repasa los ataques conocidos.
Al terminar sabrás:
Calcular palabras de la expansión de clave con RotWord, SubWord y Rcon
Explicar por qué las constantes Rcon son potencias de x en el cuerpo de 256 elementos
Descifrar con InvShiftRows, InvSubBytes e InvMixColumns en orden inverso
Saber qué ataques se conocen contra AES-128 y qué significan
Si sabes qué es un número en binario y sumar módulo 2 (sin llevadas), puedes seguirlo. Lo demás (hexadecimal, XOR, permutaciones, polinomios módulo 2 y cuerpos finitos) se explica sobre la marcha.
En la lección anterior desmontamos una ronda de AES, y en la última cuenta usamos «la clave de ronda 1» sin decir de dónde sale. Hoy cerramos el diseño de AES: cómo se fabrican las once claves de ronda a partir de los 16 bytes de la clave, cómo se descifra, y qué se sabe de los intentos de romperlo. Seguimos en el punto del relato en que AES ya ha sustituido a DES, y quedan por delante los modos de operación.
La idea
AES-128 hace un AddRoundKey antes de la primera ronda y uno al final de cada una de las diez rondas: necesita 11 claves de ronda de 16 bytes, 176 bytes en total. Alicia y Bernardo comparten solo 16. La expansión de clave estira esos 16 bytes hasta 176 con un procedimiento público y sin secretos: lo único secreto es la clave.
Para que la expansión sirva, debe cumplir dos cosas. Cada byte de la clave debe influir en muchas claves de ronda, y las claves de ronda no deben ser fáciles de relacionar entre sí. Lo primero se consigue encadenando las palabras; lo segundo, metiendo de vez en cuando una caja S y una constante distinta en cada ronda.
Descifrar es la otra mitad: como cada operación de AES es invertible, se deshace una a una en orden inverso, y las claves de ronda se usan al revés. La diferencia con DES es que aquí no hay truco de Feistel: hay que construir de verdad las operaciones inversas.
La expansión de clave
Una palabra es una cadena de 4 bytes. La clave de 16 bytes son las cuatro primeras palabras w0,w1,w2,w3 (los bytes 0 a 3 forman w0, y así sucesivamente). Las demás, hasta w43, se calculan con la regla
wi=wi−4⊕temp,temp={SubWord(RotWord(wi−1))⊕Rconi/4wi−1si i es muˊltiplo de 4,en otro caso.
RotWord rota la palabra un byte a la izquierda: (a0,a1,a2,a3)↦(a1,a2,a3,a0).
SubWord aplica la caja S de SubBytes a cada uno de los cuatro bytes.
Rconj es la palabra (rcj,00,00,00), con rcj la constante de la ronda j.
La clave de ronda r son las palabras w4r,w4r+1,w4r+2,w4r+3, colocadas como columnas de una matriz 4×4, igual que el estado.
Las constantes. Los bytes rc1,…,rc10 son las potencias x0,x1,…,x9 en F28. Se obtienen multiplicando por 02 (xtime) cada vez:
j
1
2
3
4
5
6
7
8
9
10
rcj
01
02
04
08
10
20
40
80
1b
36
Hasta 80 es solo desplazar. Luego, x8=x4+x3+x+1=1b por el polinomio con el que se construye el cuerpo, y x9=1b⋅02=36. Para qué sirven: sin ellas, las cuatro palabras de cada bloque se calcularían de la misma forma en todas las rondas, y la expansión tendría simetrías que un atacante podría aprovechar. Con una constante distinta por ronda se rompe esa simetría.
Ejemplo resuelto: de w0,…,w3 a la clave de la ronda 1
w4 (i=4 es múltiplo de 4). Partimos de w3=09cf4f3c.
RotWord: cf4f3c09.
SubWord (con la tabla de la caja S de FIPS 197, §5.1.1): S(cf)=8a, S(4f)=84, S(3c)=eb, S(09)=01, luego 8a84eb01.
XOR con Rcon1=01000000: 8b84eb01.
w4=w0⊕8b84eb01=2b7e1516⊕8b84eb01=a0fafe17.
w5,w6,w7. Ya no hay caja S, solo XOR con la palabra anterior:
w5=w1⊕w4=28aed2a6⊕a0fafe17=88542cb1.
w6=w2⊕w5=abf71588⊕88542cb1=23a33939.
w7=w3⊕w6=09cf4f3c⊕23a33939=2a6c7605.
La clave de la ronda 1 es w4w5w6w7, la matriz con esas palabras como columnas, que ya usamos en la lección anterior:
a0fafe1788542cb123a339392a6c7605.
Siguiendo igual hasta w43=b6630ca6 se llega a la clave de la ronda 10, w40w41w42w43:
d014f9a8c9ee2589e13f0cc8b6630ca6.
Las diez rondas del ejemplo
Con las claves de ronda, cifrar el bloque del ejemplo de FIPS 197,
3243f6a8885a308d313198a2e0370734,
es repetir lo que ya sabes. Esta tabla da el estado al inicio de cada ronda (el de la ronda 1 es el bloque más la clave de la ronda 0). Cada estado se lista como los 16 bytes en el orden del bloque, es decir, columna a columna (cada grupo de 8 dígitos es una columna).
Ronda
Estado al inicio de la ronda
1
193de3bea0f4e22b9ac68d2ae9f84808
2
a49c7ff2689f352b6b5bea43026a5049
3
aa8f5f0361dde3ef82d24ad26832469a
4
486c4eee671d9d0d4de3b138d65f58e7
5
e0927fe8c86363c0d9b1355085b8be01
6
f1006f55c1924cef7cc88b325db5d50c
7
260e2e173d41b77de86472a9fdd28b25
8
5a4142b11949dc1fa3e019657a8c040c
9
ea835cf00445332d655d98ad8596b0c5
10
eb40f21e592e38848ba113e71bc342d2
La ronda 10 no tiene MixColumns, y su salida es el criptograma:
c=3925841d02dc09fbdc118597196a0b32.
Descifrar: deshacer en orden inverso
Cada operación de la ronda tiene inversa.
AddRoundKey es su propia inversa: el XOR con la misma clave deshace el XOR.
InvShiftRows rota la fila r del estado r posiciones a la derecha.
InvSubBytes aplica la tabla inversa de S (que existe porque S es biyectiva): S−1(ed)=53. A mano no se calcula: se lee en la tabla 6 de FIPS 197 (§5.3.2), igual que S se lee en su tabla 4.
InvMixColumns multiplica cada columna por la matriz inversa de M en F28:
M−1=0e090d0b0b0e090d0d0b0e09090d0b0e.
Hemos comprobado con un programa que MM−1=I en F28. Los coeficientes son más «pesados» que 01,02,03 (cada uno necesita hasta tres xtime), y por eso el descifrado de AES es algo más costoso que el cifrado.
El descifrado hace, en este orden:
AddRoundKey con la clave de la ronda 10.
Para r=9,8,…,1: InvShiftRows, InvSubBytes, AddRoundKey con la clave de la ronda r e InvMixColumns.
Última ronda: InvShiftRows, InvSubBytes y AddRoundKey con la clave de la ronda 0.
Las claves de ronda se usan de la 10 a la 0. A diferencia de DES, no basta con invertir el orden de las subclaves: hay que invertir también las operaciones.
Ejemplo resuelto: el primer paso del descifrado
Descifremos c con la clave del ejemplo de FIPS 197. Sumamos la clave de la ronda 10:
Es el estado tras el ShiftRows de la ronda 10. Ahora InvShiftRows (fila 1 una posición a la derecha, fila 2 dos, fila 3 tres):
e9098972cb31075f3d327d94af2e2cb5,
y InvSubBytes. Estos son los 16 valores de la tabla inversa que hacen falta, columna a columna:
columna 1
columna 2
columna 3
columna 4
e9↦eb
cb↦59
3d↦8b
af↦1b
09↦40
31↦2e
32↦a1
2e↦c3
89↦f2
07↦38
7d↦13
2c↦42
72↦1e
5f↦84
94↦e7
b5↦d2
Queda
eb40f21e592e38848ba113e71bc342d2.
Es el estado de la fila 10 de la tabla, eb40f21e592e3884…: la entrada de la ronda 10, recuperada. Seguimos: AddRoundKey con la clave de la ronda 9, w36w37w38w39,
ac7766f319fadc2128d12941575c006e
(en el ejercicio 2 recuperarás dos de esas palabras), da
473794ed40d4e4a5a3703aa64c9f42bc,
y falta InvMixColumns. La primera columna (47,37,94,ed) da, en su primer byte,
0e⋅47⊕0b⋅37⊕0d⋅94⊕09⋅ed=87⊕fa⊕3e⊕c4=87.
La columna completa es (87,6e,46,a6) y el estado resultante,
876e46a6f24ce78c4d904ad897ecc395,
es exactamente el que salió de ShiftRows en la ronda 9. Repitiendo el proceso otras ocho veces se llega al bloque original, 3243f6a8… (lo hemos comprobado con un programa).
¿Se puede romper AES?
Ningún ataque práctico se conoce contra AES completo: nadie ha encontrado una forma de recuperar la clave sustancialmente más rápida que probarlas todas con un coste que se pueda ejecutar. En 2011, Bogdanov, Khovratovich y Rechberger publicaron, según el resumen de su artículo, el primer ataque de recuperación de clave contra AES-128 completo: un ataque de biclique con una complejidad de 2126,1 operaciones. La fuerza bruta cuesta 2128, así que el ataque es unas 2128/2126,1≈3,7 veces más rápido: menos de cuatro veces. Pero 2126,1 es todavía del orden de 1038 operaciones: un ahorro de factor pequeño sobre un número inalcanzable. Es un resultado teórico que mide el margen de seguridad de AES, no una amenaza.
Ejercicios
Ejercicio 1
Comprueba que rc9=1b y rc10=36 partiendo de rc8=80, y calcula la constante siguiente, x10.
Ver la solución
Multiplicar por 02 es xtime. Con 80=10000000, el desplazamiento a la izquierda se sale del byte (queda 00 con un bit de desbordamiento), y se hace XOR con 1b: rc9=1b. Ahora 1b=00011011 se desplaza a 00110110=36 sin desbordar, así que rc10=36. Una vez más, 36=00110110 pasa a 01101100=6c, sin desbordar. La constante siguiente es 6c (AES-128 no la usa).
Ejercicio 2
La expansión de clave se puede recorrer hacia atrás. Sabiendo w42=e13f0cc8, w43=b6630ca6 y w40=d014f9a8, calcula w39 y w36. Usa S(5c)=4a, S(00)=63, S(6e)=9f, S(57)=5b.
Ver la solución
Como 43 no es múltiplo de 4, w43=w39⊕w42, y despejamos: w39=w43⊕w42=b6630ca6⊕e13f0cc8=575c006e.
Para w40 sí hay caja S: w40=w36⊕SubWord(RotWord(w39))⊕Rcon10. Calculamos RotWord(575c006e)=5c006e57, SubWord=4a639f5b y, con Rcon10=36000000, el XOR da 7c639f5b. Despejamos: w36=w40⊕7c639f5b=d014f9a8⊕7c639f5b=ac7766f3.
Conclusión: conocida la clave de la ronda 10, se recupera la clave de cifrado entera. La expansión es invertible, así que robar una clave de ronda equivale a robar la clave.
Ejercicio 3
Calcula el primer byte de InvMixColumns de la columna (47,37,94,ed) con todas las cuentas.
Ver la solución
Primer byte: 0e⋅47⊕0b⋅37⊕0d⋅94⊕09⋅ed. Como 0e=8+4+2, 0b=8+2+1, 0d=8+4+1 y 09=8+1 (en el sentido de potencias de x), calculamos para cada byte s los valores 02s, 04s y 08s con xtime:
s
02s
04s
08s
47
8e
07
0e
37
6e
dc
a3
94
33
66
cc
ed
c1
99
29
Entonces:
0e⋅47=0e⊕07⊕8e=87.
0b⋅37=a3⊕6e⊕37=fa.
0d⋅94=cc⊕66⊕94=3e.
09⋅ed=29⊕ed=c4.
Suma: 87⊕fa⊕3e⊕c4=87.
En resumen
La expansión de clave produce w0,…,w43: cada palabra es wi−4⊕wi−1, salvo cada cuarta, donde wi−1 pasa antes por RotWord, SubWord y un XOR con Rcon.
Las constantes Rcon son las potencias x0,…,x9 de F28 y hacen distinta cada ronda.
Descifrar es deshacer cada operación en orden inverso con las claves de la 10 a la 0: InvShiftRows, InvSubBytes e InvMixColumns (con 0e,0b,0d,09).
Para el ejemplo de FIPS 197, las diez rondas llevan el bloque 3243f6a8… al criptograma 3925841d…, y el descifrado hace el camino inverso.
No se conoce ataque práctico contra AES; el primer ataque teórico de recuperación de clave contra AES-128 completo, un biclique (2011), cuesta 2126,1 frente a 2128.