Para el cifrado de un mensaje, se divide a nivel binario el mensaje en bloques de largo fijo. Este largo puede ser por ejemplo de 128 bits (4 bytes) y depende de cada algoritmo. Se llama block cipher al algoritmo que dado un bloque de largo fijo y una clave, lo transforma en un bloque cifrado (ciphertext).
Los mensajes que se desean cifrar no necesariamente cumplen con la propiedad de tener un largo múltiplo del largo fijo del bloque. Padding es una técnica que permite expandir el último bloque del mensaje hasta lograr el tamaño requerido. Esta operación debe poder ser revertida por el destinatario del mensaje. En otras palabras, el destinatario debe poder determinar con precisión en el último bloque cuántos bits corresponden al mensaje real y cuántos bits fueron agregados por la técnica de padding.
Existen múltiples técnicas de padding. Bruce Schenier, en su libro Cryptography Engineering, menciona dos:
- Agregar al final del mensaje un byte con el valor 128 y luego agregar tantos 0′s como haga falta para alcanzar el largo del bloque de largo fijo.
- Determinar el número de bytes que se requieren de padding. Supongamos que este número es n. Completar el mensaje con n bytes de valor n.
Cualquier técnica es válida mientras permita completar el mensaje hasta el largo requerido y el receptor pueda obtener con exactitud el mensaje original -sin bits extra y sin bits faltantes-.
Teniendo un mensaje de un largo adecuado, podríamos cifrar bloque por bloque. El cifrado de cada bloque sería independiente del cifrado de los otros bloques. Se llama a esta técnica ECB o Electronic Codebook. ¿Por qué no se utiliza? El problema es que en caso de que los bloques fueran iguales, el resultado sería también igual. Esto sucede a menudo en un mensaje típico y es indeseable porque brinda al atacante patrones de repetición de bloques -no queremos darle tanta información-.
Para solucionar este problema, puede utilizarse la técnica CBC o Cipher Block Chaining. Esta técnica consiste en encadenar los bloques cifrados de forma tal que el resultado del cifrado de cada bloque dependa del bloque anterior. Por lo tanto: Ci = E(k, Pi XOR Ci-1). Ci es el ciphertext del bloque número i -cadena que queremos obtener-. E es el algoritmo de cifrado (block cipher). Pi es el bloque a cifrar. XOR es la operación lógica que se aplica al Pi antes de cifrarlo. Ci-1, segundo operando de la operación XOR, es el ciphertext del bloque anterior. XOR es una operación que permite mezclar dos bloques sin perder información: sabiendo el resultado y uno de los operandos, puede determinarse con exactitud el restante operando. De esta manera, dos bloques iguales en distintas posiciones del mensaje van a arrojar un ciphertext diferente.
¿Qué sucede con el primer bloque del mensaje? Según lo que describimos hasta aquí, se necesita el ciphertext del bloque anterior para obtener el ciphertext de cada bloque. En el primer bloque no tenemos bloque anterior. Debe utilizarse para solucionar esto un vector de inicialización o IV. En el próximo artículo veremos de qué se trata.
1 Trackback(s)