¿Qué API de CryptoPP genera resultados redondos por redondos para el cifrado / descifrado AES?

3

Creé un programa que utilizaba las API de CryptoPP para implementar el modo AES ECB con una clave de 128 bits para el cifrado / descifrado del texto plano de entrada del usuario. Sé que el BCE es el modo AES menos seguro, pero es suficiente para mi programa, que solo tiene fines demostrativos básicos.

Me gustaría capturar el resultado de la ronda por resultados cuando mi programa aplique las operaciones de cifrado y descifrado AES ECB. ¿CryptoPP proporciona API para hacer esto?

En otras palabras, cuando mi programa realiza el cifrado en la entrada del usuario en texto sin formato, me gustaría mostrar el texto cifrado producido por cada una de las 10 rondas involucradas en la operación de cifrado. De manera similar, cuando mi programa realiza el descifrado en el texto cifrado generado por el AES ECB, me gustaría mostrar el texto plano recuperado producido por cada una de las 10 rondas involucradas en la operación de descifrado.

Mi programa genera una clave (con la API GenerateBlock de AutoSeededRandomPool), realiza el cifrado (pasando una instancia "ECB_Mode :: Encryption" a un StreamTransformationFilter) y realiza un descifrado (al pasar una instancia de "ECB_Mode :: Decryption" a un StreamTransformationFilter) . Mi programa solicita al usuario que use texto sin formato para operar, genera el texto cifrado producido al aplicar la API de cifrado AES ECB de CryptoPP en el texto sin formato, y luego genera el texto sin formato recuperado al aplicar la API de descifrado AEC ECB de CryptoPP.

Estoy publicando esta pregunta después de haber investigado sin éxito los recursos de CryptoPP para encontrar formas de obtener resultados de la operación AES ronda por ronda. Muchas gracias por la asistencia prestada.

    
pregunta ad479 03.11.2015 - 17:29
fuente

1 respuesta

0

De hecho, la "salida de cada ronda" no está bien definida. La estructura del cifrado AES es una secuencia de operaciones que se parece a esto:

Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
begin
   byte  state[4,Nb]
   state = in
   AddRoundKey(state, w[0, Nb-1]) 
   // See Sec. 5.1.4
   for round = 1 step 1 to Nr–1
      SubBytes(state) 
      // See Sec. 5.1.1
      ShiftRows(state) 
      // See Sec. 5.1.2
      MixColumns(state) 
      // See Sec. 5.1.3
      AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
   end for
   SubBytes(state)
   ShiftRows(state)
   AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
   out = state
end

Este pesudo-código se extrae directamente de la especificación AES ( FIPS 197 ) . AES (con una clave de 128 bits) se puede definir como que consiste en diez rondas, donde cada ronda consiste en unas pocas operaciones (SubBytes, ShiftRows, MixColumns, AddRoundKey). Sin embargo, esa descripción debería ser enmendada con un AddRoundKey adicional, y sin un MixColumns en la ronda final. El pseudocódigo anterior está estructurado como nueve rondas, donde cada ronda es la secuencia SubBytes-ShiftRows-MixColumns-AddRoundKey; y hay algunas operaciones antes y después de esta secuencia de nueve rondas.

Lo que constituye una "ronda" es arbitrario aquí; hubiera sido igualmente válido definir una ronda como la secuencia ShiftRows-MixColumns-AddRoundKey-SubBytes; Las operaciones de inicio y finalización habrían sido un poco diferentes. Ninguna de las dos descripciones es más estándar o correcta que cualquier otra.

Una complicación adicional es que la secuencia de operaciones es susceptible de transformaciones algebraicas. Por ejemplo, ShiftRows y SubBytes conmutan; y AddRoundKey y MixColumns se pueden hacer en orden inverso, siempre que las subclaves se transformen en consecuencia; esto se describe en FIPS 197, sección 5.3.5, para el descifrado AES ("Cifrado inverso equivalente"). Esto aumenta el número de descripciones posibles de rondas AES.

Además, las implementaciones de AES "normales" (basadas en tablas) fusionarán algunas operaciones juntas, normalmente SubBytes, ShiftRows y MixColumns, por la magia del álgebra lineal. Dado que en realidad no ocurren como fases separadas, no existen salidas individuales.

Dado que la salida de la ronda no está bien definida, las implementaciones tienen poco sentido para proporcionar un acceso a estos valores.

Si desea, con fines pedagógicos, imprimir valores intermedios, es mejor que seleccione una implementación que siga la letra de la especificación (a expensas del rendimiento), es decir, no Crypto ++; de hecho, debe escribir el suyo propio (si imprime valores intermedios, entonces no está haciendo nada de forma segura , por lo que se justifica la escritura de su propio código).

    
respondido por el Tom Leek 03.11.2015 - 20:07
fuente

Lea otras preguntas en las etiquetas