Idioma: Español

tools / aes

aes/

Cifrado y descifrado simétrico con AES. Puedes elegir el modo, el relleno, el formato de la clave y del IV y el juego de caracteres; el resultado coincide con Java y CryptoJS, y tu clave nunca sale del navegador.

Texto plano

Texto cifrado

Historial

Cada cifrado o descifrado correcto se guarda automáticamente. Se conservan los últimos 20, solo en el navegador de este dispositivo. Las claves nunca se guardan, pero sí los IV y el texto plano descifrado, así que en un equipo compartido borra el historial al terminar.

AES, DES y RSA: qué son y en qué se diferencian

AES y DES son cifrados simétricos: la misma clave cifra y descifra, como una llave que sirve tanto para cerrar como para abrir una puerta. Son rápidos y adecuados para grandes cantidades de datos; lo difícil es hacerle llegar esa clave al otro lado de forma segura.

DES es un estándar antiguo de los años 70 con una clave efectiva de solo 56 bits, que hoy se puede romper por fuerza bruta con hardware especializado o clústeres de equipos, así que solo sirve para conectar con sistemas antiguos que todavía lo usan. AES sustituyó a DES como estándar. Usa claves de 128, 192 o 256 bits, hoy no tiene ningún ataque práctico y es la opción por defecto para cifrar datos.

RSA es asimétrico: hay un par de claves. La clave pública se puede dar a cualquiera y sirve para cifrar; la clave privada la guardas tú y sirve para descifrar, como un buzón en el que cualquiera puede echar cartas pero que solo tú puedes abrir. No hace falta acordar una clave compartida de antemano, pero RSA es lento y solo puede cifrar unos cientos de bytes cada vez. Los sistemas reales suelen combinar ambos: RSA cifra una clave AES generada al azar para el otro lado, y AES cifra los datos reales.

¿Qué es un modo de cifrado y cuál elegir?

AES cifra 16 bytes cada vez; el modo decide cómo se divide un dato más largo en bloques y cómo se enlazan entre sí. ECB cifra cada bloque por separado, así que un contenido idéntico da un texto cifrado idéntico y deja ver patrones; evítalo. CBC mezcla cada bloque con el bloque cifrado anterior antes de cifrarlo, y el primero con el IV; es la opción más habitual. CFB, OFB y CTR convierten AES en un flujo de clave que se combina con los datos mediante XOR byte a byte, por lo que no necesitan relleno. GCM añade una etiqueta de autenticación (Tag) sobre CTR, de modo que un texto cifrado alterado no se puede descifrar; hoy es el modo recomendado.

Para qué sirven el IV y el relleno

El IV (vector de inicialización) hace que el mismo contenido se cifre de forma distinta cada vez. No tiene que ser secreto y puede viajar junto al texto cifrado, pero nunca reutilices uno con la misma clave, sobre todo en GCM. Todos los modos excepto ECB necesitan IV: para GCM se recomiendan 12 bytes y los demás modos exigen exactamente 16 bytes.

ECB y CBC necesitan que la longitud de los datos sea múltiplo de 16 bytes, así que los datos más cortos se completan según el relleno elegido. PKCS5Padding y PKCS7Padding son idénticos en AES y los más habituales. ZeroPadding rellena con ceros y al descifrar elimina todos los bytes cero del final, así que si el texto plano termina en bytes cero, los pierde. NoPadding no añade nada, por lo que acertar con la longitud es cosa tuya. GCM no usa relleno.

Equivalencias con Java y CryptoJS

Cipher.getInstance("AES/CBC/PKCS5Padding") de Java significa CBC con PKCS5Padding; si solo escribes "AES", el valor por defecto es ECB con PKCS5Padding. En Java, CTR y GCM solo funcionan con NoPadding, y el Tag de GCM debe tener entre 96 y 128 bits. CryptoJS.pad.Pkcs7 de CryptoJS es PKCS7Padding, y ZeroPadding, AnsiX923, Iso10126 e Iso97971 coinciden por nombre. Si pasas una contraseña en forma de string a CryptoJS.AES.encrypt, genera la clave por su cuenta y devuelve un resultado que empieza por U2FsdGVkX1; ese uso no está soportado aquí, así que pasa una clave de 16, 24 o 32 bytes y un IV.

Qué son el Tag y el AAD de GCM

El Tag es el valor de verificación que calcula GCM; son los últimos bytes del texto cifrado (16 bytes si el Tag es de 128 bits). El AAD son datos autenticados adicionales, como la cabecera de un mensaje. No se cifra, pero entra en la verificación, así que al descifrar debes introducir el mismo AAD o la verificación falla.

Preguntas frecuentes

¿Qué hago si aparece «La clave tiene N bytes» o «El IV tiene N bytes»?

Primero comprueba que el formato sea el correcto: los mismos 32 caracteres son 32 bytes en formato string, pero solo 16 bytes en hex. Una clave AES debe tener 16, 24 o 32 bytes y, salvo en ECB y GCM, el IV debe tener exactamente 16 bytes; aquí no se rellena ni se recorta nada por ti, y el número de bytes actual aparece junto a las etiquetas Clave e IV. En formato string el recuento depende del juego de caracteres elegido, así que un carácter chino ocupa 3 bytes en UTF-8. Si tu backend procesa antes la contraseña, por ejemplo rellenándola con ceros o calculando su hash, obtén primero los bytes finales e introdúcelos en hex o base64.

¿Qué hago si al descifrar aparece «relleno no válido»?

Significa que el último bloque descifrado no cumple la regla de relleno elegida. Normalmente la clave, el IV, el modo o el relleno no coinciden con los que se usaron al cifrar, o el texto cifrado se copió incompleto. Compara cada parámetro con el lado que cifró; un formato de clave o de texto cifrado incorrecto (hex en lugar de base64, o al revés) provoca el mismo error. ZeroPadding y NoPadding no comprueban el relleno, así que no producen este error, pero el resultado sale ilegible si los parámetros son incorrectos.

El principio del texto descifrado sale ilegible, o aparece que el resultado no es texto UTF-8 válido

Comprueba primero el IV. Cuando el texto cifrado ocupa más de un bloque, un IV incorrecto en los modos CBC y CFB estropea solo el primer bloque de 16 bytes; el resto sale bien y no aparece ningún error de relleno, así que ves caracteres ilegibles al principio y texto correcto después. Si el mensaje dice que el resultado no es texto válido, puede que el juego de caracteres sea distinto del usado al cifrar, por ejemplo que el otro lado usara GBK. Si pones el formato de salida en hex, puedes comprobar primero los propios bytes descifrados.

¿Qué hago si al descifrar con GCM aparece «falló la verificación del Tag»?

Significa que la clave, el IV, el AAD o la longitud del Tag no coincide con la del cifrado, o que el texto cifrado fue modificado. Los últimos bytes de la entrada se tratan como el Tag, con la longitud indicada en la opción «Longitud del Tag» (128 bits por defecto, es decir, 16 bytes), así que el texto cifrado y el Tag deben introducirse juntos; si el otro lado te da el Tag por separado, añádelo primero al final del texto cifrado. El formato del AAD es hex por defecto, así que cámbialo cuando introduzcas contenido en string, y si al cifrar no se usó AAD, déjalo vacío al descifrar.

Mi resultado no coincide con el de Java, Python u otro backend. ¿Cómo lo reviso?

Revisa en este orden: modo y relleno, formato y número de bytes de la clave y el IV, juego de caracteres, y formatos de entrada y salida. El texto plano en formato string no se recorta, así que un salto de línea de más al final son otros datos. Aquí CTR, CFB y OFB también rellenan según el relleno elegido, por lo que con PKCS5Padding el texto cifrado es más largo que el texto plano; si tu backend usa NoPadding, elige NoPadding también aquí. CFB aquí es la variante de bloque completo de 128 bits, así que no coincidirá con un backend que use CFB8.

¿El texto cifrado debe ir en hex o en base64? ¿Qué pasa si me equivoco?

Sigue lo que produzca el otro lado: un texto formado solo por 0-9 y a-f es hex, y uno con letras mayúsculas y minúsculas, +, / o un = final es base64. Equivocarse al descifrar no siempre falla de inmediato, porque todos los caracteres hex también son caracteres base64 válidos; simplemente obtienes bytes incorrectos, y más tarde aparece como «no es múltiplo de 16» o como relleno no válido. Se acepta base64 con - y _ (la forma segura para URL) o sin los = finales, y en hex se ignoran los espacios, los dos puntos y el prefijo 0x.

Qué guarda el historial y si se sube a algún sitio

Solo existe en el localStorage del navegador de este dispositivo y nunca se sube; el código de la página no hace ninguna petición de red. Se añade un registro tras cada cifrado o descifrado correcto, se conservan hasta 20, y no se guarda nada cuya entrada o resultado supere los 20 000 caracteres. Cada registro contiene los parámetros, el IV, el AAD, la entrada y el resultado, además de una huella de 8 caracteres derivada de la clave (los caracteres que van después de # en cada registro, que sirven para saber si es la misma clave), pero nunca la clave en sí, así que tras pulsar «Cargar» tienes que introducir la clave de nuevo. Cada registro se puede eliminar por separado, y en un equipo compartido pulsa «Borrar historial» al terminar.

¿Puede generar una clave o un IV aleatorio por mí?

No. No hay botón de generar, así que tú introduces la clave y el IV. El mismo texto plano, clave, IV y parámetros dan siempre el mismo resultado; solo el relleno ISO10126 mezcla bytes aleatorios y por eso lo cambia. Si necesitas valores aleatorios, genéralos tú; por ejemplo, openssl rand -hex 16 en la línea de comandos imprime 16 bytes, que puedes introducir con el formato en hex.