tools / des
des/
Cifrado y descifrado simétrico con DES, para trabajar con sistemas antiguos que aún lo usan. 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?
DES cifra 8 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 DES en un flujo de clave que se combina con los datos mediante XOR byte a byte, por lo que no necesitan relleno.
Clave, IV y relleno
La clave de DES tiene 8 bytes, pero el bit menos significativo de cada byte es un bit de paridad que no se usa, así que la clave efectiva es de solo 56 bits. Si la clave tiene más de 8 bytes, solo se usan los primeros 8, igual que en DESKeySpec de Java y CryptoJS; si es más corta, se rechaza. Todos los modos excepto ECB necesitan un IV de 8 bytes. No tiene que ser secreto, pero no lo reutilices con la misma clave.
ECB y CBC necesitan que la longitud de los datos sea múltiplo de 8 bytes, así que los datos más cortos se completan según el relleno elegido. PKCS5Padding y PKCS7Padding son idénticos en DES 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.
Equivalencias con Java y CryptoJS
Cipher.getInstance("DES/CBC/PKCS5Padding") de Java significa CBC con PKCS5Padding; si solo escribes "DES", el valor por defecto es ECB con PKCS5Padding. En Java, CTR solo funciona con NoPadding. Los modos y rellenos de CryptoJS.DES.encrypt coinciden por nombre, y CryptoJS.pad.Pkcs7 es PKCS7Padding. Para sistemas nuevos, usa AES.
Preguntas frecuentes
¿Se puede cifrar y descifrar 3DES (DESede, TripleDES) aquí?
No, aquí solo está implementado el DES simple. Una clave 3DES tiene 16 o 24 bytes; si la pegas aquí, solo se usan los primeros 8, así que el resultado es distinto al de 3DES, y junto al campo de la clave también aparece el aviso «solo se usan los primeros 8 bytes». Para 3DES, usa una herramienta que admita DESede.
¿Qué hago si aparece «La clave tiene N bytes; una clave DES necesita al menos 8 bytes»?
Con menos de 8 bytes aparece un error y aquí no se rellena con ceros, así que complétala tú hasta 8 bytes. Un descuido más probable es el formato: si una clave hex de 16 caracteres se introduce con el formato de la clave en string, se trata como 16 bytes de texto y solo se usan los primeros 8 caracteres. No hay error, solo el aviso «solo se usan los primeros 8 bytes» junto al campo de la clave y debajo del resultado, y la salida no coincidirá. En formato string el recuento depende del juego de caracteres elegido, así que un carácter chino ocupa 3 bytes en UTF-8.
¿Qué hago si aparece «este modo necesita un IV de exactamente 8 bytes»?
En DES el IV debe tener exactamente 8 bytes, no los 16 de AES, en todos los modos excepto ECB. Una clave de más de 8 bytes se recorta a los primeros 8, pero el IV no: si es más largo o más corto, da error, así que un IV de 16 bytes tomado de unos ajustes de AES hay que cambiarlo a 8 bytes. Comprueba también el formato: 16 caracteres hex son 8 bytes, mientras que los mismos 16 caracteres en formato string son 16 bytes. ECB no necesita IV y oculta el campo del IV.
¿Qué hago si al descifrar aparece «relleno no válido» o «no es múltiplo de 8»?
Si la longitud del texto cifrado no es múltiplo de 8, normalmente se copió incompleto o se confundieron hex y base64. Un relleno no válido suele indicar que la clave, el IV, el modo o el relleno no coinciden con los usados al cifrar. ZeroPadding y NoPadding no comprueban el relleno, así que nunca dan 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 8 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.
Mi resultado no coincide con el de Java o CryptoJS. ¿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 64 bits, así que no coincidirá con un backend que use CFB8.
La salida de CryptoJS.DES.encrypt empieza por U2FsdGVkX1. ¿Se puede descifrar aquí?
No. Cuando pasas un string como clave a CryptoJS.DES.encrypt(message, string), CryptoJS lo trata como una contraseña: añade una sal aleatoria y deriva la clave y el IV como hace OpenSSL, y el resultado empieza por U2FsdGVkX1. Ese formato no está soportado aquí. Para que coincida con esta herramienta, convierte la clave a bytes en CryptoJS con CryptoJS.enc.Utf8.parse y pásala, e indica iv, mode y padding de forma explícita.
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, la entrada y el resultado, además de una huella de 8 caracteres derivada de los primeros 8 bytes 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.