Cómo proteger los algoritmos de cifrado simétrico en Java
18 de octubre de 2023
0 minutos de lecturaEn nuestro mundo conectado, proteger los datos digitales se ha vuelto una prioridad fundamental. Dada la amplia difusión de las aplicaciones Java en distintos sectores, desde la banca hasta la atención médica, debemos destacar la importancia del cifrado. El cifrado convierte datos legibles, o texto sin formato, en datos ilegibles, o texto cifrado, para garantizar que, aunque alguien intercepte los datos cifrados, no pueda acceder a ellos sin autorización.
La primera decisión que debes tomar como desarrollador es si necesitas cifrar los datos. Aunque parezca una pregunta extraña, el principio clave del cifrado es que el texto cifrado se puede revertir al texto original. Por ejemplo, cuando hablamos de contraseñas, no queremos cifrarlas porque no queremos poder «descifrar» el texto original. Por eso, recurrimos al hashing de contraseñas en lugar del cifrado.
Cifrado en Java
Las aplicaciones Java suelen manejar datos confidenciales, como información de clientes, datos financieros y registros de transacciones. Como desarrollador de Java, usar algoritmos de cifrado robustos es fundamental para mantener la integridad y confidencialidad de los datos sensibles. Esto protege a tus usuarios y cualquier dato esencial que tengas dentro de tu sistema.
Cifrado simétrico y asimétrico
En términos generales, podemos distinguir dos tipos de cifrado: simétrico y asimétrico. Cada tipo funciona de una manera fundamentalmente distinta y tiene diferentes casos de uso.
El cifrado simétrico usa la misma clave para cifrar y descifrar, por lo que es más rápido, pero menos seguro cuando es necesario compartir la clave. Por otro lado, el cifrado asimétrico usa un par de claves (pública y privada). La clave pública se usa para cifrar y la privada, para descifrar. Si bien el cifrado simétrico es adecuado para situaciones en las que se deben cifrar grandes volúmenes de datos, el cifrado asimétrico es ideal para compartir claves de forma segura a través de una red. Aunque distinguimos dos tipos de cifrado, en este artículo nos enfocaremos únicamente en el cifrado simétrico en aplicaciones Java.
Al usar cifrado simétrico, lo mejor es recurrir a servicios que aprovechen módulos de seguridad de hardware (HSM) para administrar claves y patrones de cifrado de sobres. Esto simplifica la administración de claves, que es la parte más difícil de una solución de cifrado. Sin embargo, si no puedes usar un servicio como Amazon Key Management Service (KMS) y aun así quieres hacerlo, la siguiente información te mostrará cómo hacerlo de forma segura. En el resto de este artículo, nos centraremos en implementar el cifrado simétrico en tu aplicación Java usando los paquetes javax.crypto.
Conoce los algoritmos de cifrado obsoletos y sus riesgos
A pesar de la importancia del cifrado, no todos los algoritmos de cifrado son iguales. Se ha descubierto que algunos algoritmos de cifrado antiguos u «obsoletos», como DES (Data Encryption Standard) o 3DES, tienen vulnerabilidades que los atacantes pueden explotar. En otro momento se consideraron seguros, pero los avances en la potencia de cómputo y las técnicas de criptoanálisis los han vuelto inseguros.
Usar algoritmos de cifrado inseguros en tus aplicaciones Java puede generar riesgos. Un atacante que acceda a tus datos cifrados podría descifrarlos si el algoritmo de cifrado está obsoleto y tiene vulnerabilidades conocidas. Esto podría provocar una filtración de datos con consecuencias potencialmente devastadoras para tus usuarios y tu organización.
Recomendaciones sobre algoritmos y modos de cifrado
En cuanto a los algoritmos de cifrado simétrico, la fundación OWASP recomienda actualmente AES (Advanced Encryption Standard) con una clave de al menos 128 bits, aunque se prefieren 256 bits. Además, debes usar el algoritmo con un modo seguro. Asimismo, los estándares y las directrices criptográficas del NIST aprueban el cifrado AES como técnica de cifrado por bloques.
Hay varios modos disponibles para cifrados como AES. Estos modos tienen distintas características de seguridad y rendimiento. En cuanto a los modos, evita ECB (Electronic Codebook), que no ofrece una confidencialidad adecuada de los mensajes. En su lugar, usa modos como CCM (Counter with CBC-MAC) o GCM (Galois/Counter Mode). Ambos son modos autenticados y garantizan la integridad, confidencialidad y autenticidad de los datos.
Cómo identificar algoritmos de cifrado débiles en Java
Es relativamente sencillo usar las API de javax.crypto para implementar un pequeño servicio de cifrado en Java. A continuación, se muestra un ejemplo de EncryptionService en Java basado en el algoritmo DES obsoleto y el modo ECB.
Ahora que incorporamos a un proyecto un algoritmo de cifrado que sabemos que es inseguro, usaremos el servicio gratuito de Snyk para detectar este uso inseguro y orientarnos hacia una mejor solución.
Primero, crea una cuenta gratuita de Snyk. Puedes empezar fácilmente con tu cuenta de GitHub, Bitbucket, Azure AD o Docker.
Luego conecté mi repositorio de GitHub a Snyk. El análisis estático de Snyk Code me advierte de inmediato que mi aplicación usa un algoritmo criptográfico defectuoso o riesgoso. La advertencia es acertada, ya que el servicio anterior contiene varias referencias a DES. El motor de Snyk Code también me recomienda considerar el uso de AES, en consonancia con las recomendaciones de OWASP.

Aunque uso AES en el breve fragmento de código que aparece a continuación, uso el modo CBC, que no se considera seguro.
Snyk también identifica el uso de modos inseguros, entre otras cosas. La siguiente captura de pantalla se tomó del plugin de Snyk, que analiza mi código dentro de IntelliJ IDEA y ofrece información útil, como ejemplos de correcciones externas.

Cambiar EncryptionService por una versión que use AES/GCM/NoPadding, como la que se muestra a continuación, es una solución mucho mejor que la anterior y está en línea con las recomendaciones actuales de OWASP.
Revisa continuamente los algoritmos de cifrado de tus aplicaciones Java
Si bien es fundamental actualizar los algoritmos de cifrado obsoletos, también es importante supervisar continuamente tu base de código para detectar nuevos problemas de seguridad. Los algoritmos de cifrado que se consideran seguros en el momento de escribir este artículo seguramente quedarán obsoletos en unos años.
Por eso, analizar e identificar estos problemas de forma proactiva debe ser una actividad continua. Esto no se aplica únicamente a los algoritmos de cifrado, sino también, por supuesto, a otros problemas del código que mantienes. Adoptar y usar una herramienta de pruebas de seguridad de análisis estático (SAST), como Snyk Code, te ayudará a reconocer, identificar y mitigar estos problemas fácilmente antes de que causen daños.
Snyk Code para Java puede ayudarte gratis
Snyk Code es una herramienta de pruebas de seguridad de aplicaciones estáticas (SAST) de última generación que identifica vulnerabilidades de seguridad en tu base de código. Es compatible con varios lenguajes de programación, incluido Java, y analiza el código para brindar comentarios en tiempo real a los desarrolladores. Puedes integrar Snyk Code en tu canalización de CI/CD para analizar automáticamente el código con cada confirmación y detectar y corregir problemas de seguridad en las primeras etapas del ciclo de desarrollo. Además, puedes conectarlo a tu repositorio de Git, usarlo desde la línea de comandos con nuestra CLI e integrarlo con todos los IDE populares para Java.
Así puedes detectar problemas en tu código de forma temprana y frecuente en cada etapa del ciclo de desarrollo. Y lo más importante: puedes usarlo gratis si te registras en Snyk a continuación.
Comienza con Capture the Flag
Aprende a resolver desafíos de Capture the Flag con nuestro taller virtual 101 a pedido.
Los ejemplos de código de esta publicación de blog están disponibles en GitHub para que puedas experimentar con ellos. Si quieres encontrar más recursos útiles sobre seguridad para desarrolladores de Java, consulta lo siguiente:
Usa JLink para crear imágenes de Docker más pequeñas para tu aplicación Java de Spring Boot
Cómo prevenir ataques de Cross-Site Scripting (XSS) en aplicaciones Java con Snyk Code
Cómo mitigar las vulnerabilidades de path traversal en Java con Snyk Code
Prácticas recomendadas para administrar dependencias de Java
10 prácticas recomendadas para crear un contenedor de Java con Docker



