java - para - Tamaño de los datos después del cifrado AES/CBC y AES/ECB
java codigo para encriptar (8)
AES funciona en bloques de 128 bits (16 bytes) y convierte bloques de texto sin formato en bloques de texto cifrado de la misma longitud. Acolcha el último bloque si es más corto que 16 bytes, por lo que su fórmula parece correcta.
Me gustaría saber el tamaño de los datos después del cifrado AES para evitar el almacenamiento en búfer de mis datos posteriores a AES (en el disco o la memoria) principalmente para conocer el tamaño.
Uso 128 bit AES y javax.crypto.Cipher
y javax.crypto.CipherInputStream
para el cifrado.
Algunas pruebas realizadas con varios tamaños de entrada muestran que el tamaño de encriptación posterior calculado es el siguiente:
long size = input_Size_In_Bytes;
long post_AES_Size = size + (16 - (size % 16));
Pero no estoy seguro de si la fórmula anterior es aplicable para todos los tamaños de entrada posibles.
¿Hay alguna manera de calcular el tamaño de los datos después de aplicar el cifrado AES, por adelantado, sin tener que almacenar en búfer los datos cifrados (en el disco o la memoria) para conocer su tamaño posterior a la encriptación?
AES tiene un tamaño de bloque fijo de 16 bytes independientemente del tamaño de la clave. Suponiendo que usa PKCS 5/7 relleno, use esta fórmula,
cipherLen = (clearLen/16 + 1) * 16;
Tenga en cuenta que si el texto claro es múltiple del tamaño del bloque, se necesita un bloque completamente nuevo para el relleno. Digamos que el texto claro es de 16 bytes. El texto de cifrado tendrá 32 bytes.
Es posible que desee almacenar IV (Vector inicial) con texto cifrado. En ese caso, necesita agregar 16 bytes más para IV.
AES, como un cifrado de bloque, no cambia el tamaño. El tamaño de entrada siempre es el tamaño de salida.
Pero AES, al ser un cifrado de bloques, requiere que la entrada sea múltiple de tamaño de bloque (16 bytes). Para esto, los esquemas de relleno se usan como el popular PKCS5 . Entonces, la respuesta es que el tamaño de sus datos cifrados depende del esquema de relleno utilizado. Pero, al mismo tiempo, todos los esquemas de relleno conocidos redondearán hasta el siguiente tamaño del módulo 16 (el tamaño AES tiene un tamaño de bloque de 16 bytes).
Depende del modo en que usa AES. Lo que tienes es preciso para la mayoría de los modos orientados a bloque, como ECB y CBC. OTOH, en el modo CFB (por ejemplo) básicamente estás usando AES para producir una secuencia de bytes, que usas XOR con bytes de la entrada. En este caso, el tamaño de la salida puede seguir siendo el tamaño de la entrada en lugar de redondearse al siguiente tamaño de bloque como se indicó anteriormente.
El cifrado AES siempre funciona en bloques de 16 bytes (128 bits). Si el número de bytes de entrada no es un múltiplo exacto de 16, se rellena. Es por eso que 16 parece ser el "número mágico" en su cálculo. Lo que tienes debe funcionar para todos los tamaños de entrada.
En términos generales, para una encriptación de cifrado de bloque:
CipherText = PlainText + Block - (Bloque MOD de texto plano)
el tamaño del texto cifrado se calcula como el tamaño del texto sin formato extendido al siguiente bloque. Si se usa relleno y el tamaño del texto plano es un múltiplo exacto del tamaño del bloque, se agregará un bloque adicional que contiene información de relleno.
AES usa un tamaño de bloque de 16 bytes, lo que produce:
CipherText = PlainText + 16 - (Texto plano MOD 16)
Fuente: http://www.obviex.com/articles/CiphertextSize.pdf
Nota:
- CipherText y PlainText representan el tamaño del texto de cifrado y el tamaño del texto sin formato en consecuencia.
Existen enfoques para almacenar información encriptada que evita la necesidad de cualquier relleno siempre que el tamaño de los datos sea al menos igual al tamaño del bloque. Una pequeña dificultad es que si se permite que el tamaño de los datos sea menor que el tamaño del bloque, y si debe ser posible reconstruir el tamaño preciso de los datos, incluso para bloques pequeños, la salida debe ser al menos un poco más grande que el entrada, [i] independientemente [/ i] del tamaño de datos.
Para comprender el problema, tenga en cuenta que hay 256 ^ N archivos posibles que tienen N bytes de longitud, y la cantidad de archivos posibles que no exceden de N bytes de longitud es 256 ^ N más la cantidad de archivos posibles que no son mayores que N -1 bytes de largo (hay un archivo posible que tiene cero bytes de longitud, y 257 archivos posibles que no tienen más de un byte de longitud).
Si el tamaño del bloque es de 16 bytes, habrá 256 ^ 16 + 256 ^ 14 + 256 ^ 13, etc. posibles archivos de entrada que no tengan más de 16 bytes de longitud, pero solo 256 ^ 16 archivos de salida posibles que no sean más de 16 bytes de longitud (ya que los archivos de salida no pueden ser menores de 16 bytes). Por lo tanto, al menos algunos posibles archivos de entrada de 16 bytes deben crecer. Supongamos que se convertirían en 17 bytes. Hay 256 ^ 17 posibles archivos de salida de diecisiete bytes; si alguno de ellos se utiliza para manejar entradas de 16 bytes o menos, no habrá suficiente disponible para manejar todos los archivos de entrada de 17 bytes posibles. No importa cuán grande pueda ser la entrada, algunos archivos de ese tamaño o más deben crecer.
Si su longitud de entrada es menor que el tamaño máximo de int puede usar Cipher.getOutputSize(int)