1. La respuesta corta
Sí, es real y conviene actuar esta semana. Afecta a cualquier aplicación Java que se conecte por HTTPS a otros servidores: pasarelas de pago, bancos, APIs o servicios de la Administración. Un atacante situado en medio de la red puede hacerse pasar por ese servidor y leer o cambiar lo que viaja. No es una puerta abierta desde internet, pero el arreglo es tan barato que no compensa esperar.
Si puedes actualizar Java, instala la versión del 24 de octubre. Si no puedes, retira hoy las cuatro raíces con keytool. En los dos casos, reinicia y compruébalo.
2. Qué ha pasado, en 30 segundos
eMudhra, una autoridad de certificación india que vende certificados con la marca emSign, generó en abril de 2025 ocho certificados intermedios con un fallo grave: sus claves privadas eran números diminutos. Una era literalmente el 4. Cualquiera puede recalcularlas a partir del propio certificado, que es público.
Con una de esas claves se puede firmar un certificado válido para cualquier dominio. El 17 de octubre de 2026 un investigador lo comunicó a los navegadores, que los bloquearon en pocos días. eMudhra los revocó el 18 y Sectigo, que había firmado versiones cruzadas, el 19. Java siguió confiando en ellos hasta que Oracle publicó dos alertas de emergencia fuera de su calendario trimestral.
| Alerta de Oracle | Fecha | Qué corrige |
|---|---|---|
| CVE-2026-91403 | 21 de octubre | Deja de confiar en los 8 intermedios y en sus versiones firmadas por Sectigo. |
| CVE-2026-114820 | 24 de octubre | Retira 4 raíces del almacén: las 2 relacionadas con los intermedios (emSign ECC Root CA - G3 y AAA Certificate Services) y otras 2 de eMudhra. Es la versión que debes tener. |
3. Por qué Java es el eslabón débil
Tu navegador ya estaba protegido. Tu aplicación Java no, por tres motivos que conviene conocer porque se repetirán en el próximo incidente.
Java trae su propia lista de autoridades de confianza, el fichero cacerts. No recibe los bloqueos que Chrome, Firefox o Windows distribuyen solos.
Por defecto no consulta si un certificado ha sido revocado. Que eMudhra los revocara no cambia nada para Java.
No exige que el certificado figure en los registros públicos de Certificate Transparency. Un certificado falso que nunca se registró pasa sin que esos registros lo delaten.
Qué podría hacer un atacante en medio
- Leer credenciales, tokens de API y datos personales que tu aplicación envía a sus proveedores.
- Cambiar respuestas: el estado de un pago, un importe o el resultado de una validación.
- Colar una dependencia maliciosa en una compilación con Maven o Gradle.
- Hacer pasar por firmado un JAR malicioso, porque dos de los intermedios servían para firmar código.
Barato y difícil de detectar
Las claves se podían recuperar desde abril de 2025 y una ya circula publicada. Un certificado falso usado contra Java no tiene por qué aparecer en los registros públicos. No hay explotación confirmada, pero tampoco se puede descartar.
Hay que estar en medio
El atacante necesita controlar el camino de red: una wifi, un DNS envenenado, un router o un proxy. Red Hat, en una valoración preliminar con supuestos de ataque más exigentes, lo deja en 6,8. El riesgo está en las conexiones que tu Java abre hacia fuera, no en las que recibe tu web.
4. ¿Me afecta? Compruébalo en un minuto
Afecta a Oracle Java SE 8, 11, 17, 21, 25 y 27, a GraalVM y a cualquier distribución de OpenJDK cuyo almacén conserve esas raíces. También a las versiones sin soporte y a las aplicaciones que traen su propio Java, como AutoFirma, OpenSearch o los entornos de desarrollo. Lo más rápido es mirarlo.
Paso 1. Localiza el java.home de cada servicio y guárdalo en la variable JH:
java -XshowSettings:properties -version 2>&1 | grep java.home
JH="/opt/java/jdk-21"
KS="$JH/lib/security/cacerts"
Paso 2. Descarga la comprobación oficial de OpenJDK y ejecútala con el mismo Java que usa el servicio. Con Java 11 o superior:
curl -fsSLO https://cr.openjdk.org/~mr/CheckCerts.java &&
"$JH/bin/java" CheckCerts.java
Con Java 8 a 10, o si ese Java no trae compilador (por ejemplo, un JRE), compílala con el javac de cualquier JDK y ejecuta la clase con el Java del servicio. Los avisos de javac son normales:
curl -fsSLO https://cr.openjdk.org/~mr/CheckCerts.java &&
javac -source 8 -target 8 CheckCerts.java &&
"$JH/bin/java" -cp . CheckCerts
En Windows, la comprobación va incluida en los bloques de la opción 2.
Si responde No bad root certificates found, ese almacén está limpio. Si muestra BAD ROOT con emSign ECC Root CA - G3 o AAA Certificate Services, sigue leyendo. Las raíces emSign Root CA - G1 y G2 no están ligadas a los intermedios comprometidos, aunque Oracle también las retira.
Ojo: comprueba el almacén del Java con el que la lanzas. Si un servicio arranca con otro almacén, por ejemplo con la opción -Djavax.net.ssl.trustStore, revísalo aparte.
He recuperado las ocho claves privadas a partir de los certificados públicos en segundos: todas son números menores que 256 y la del intermedio EM OV TLS CA - G3C es, literalmente, el 4. Y en un Java 25.0.3 sin corregir, la conexión a los servidores de prueba del incidente responde 200 como si nada. Tras retirar las cuatro raíces, Java la rechaza y las webs de control que probé siguen funcionando.
5. Opción 1: actualizar Java (lo recomendable)
Es la vía limpia. Instala la versión de tu rama publicada el 24 de octubre, que bloquea los intermedios y además retira las raíces. Las del 21 de octubre, como la 21.0.13.0.2, solo hacen lo primero.
| Rama | Versión de Oracle con el arreglo completo |
|---|---|
| Java 8 | 8u511-b33 |
| Java 11 | 11.0.33.0.3 |
| Java 17 | 17.0.21.0.3 |
| Java 21 | 21.0.13.0.3 |
| Java 25 | 25.0.5.0.3 |
| Java 27 | 27.0.1.0.3 |
Si usas otra distribución de OpenJDK, como Temurin, Corretto, Zulu o la de Red Hat, busca en sus notas de versión JDK-8395690 o CVE-2026-114820 y confírmalo con la comprobación del punto 4. GraalVM de Oracle también está afectado y tiene su propia actualización.
Las versiones sin soporte, como Java 23 o 26, ya no reciben parches. Usa la opción 2 y planifica el salto a una versión con soporte a largo plazo. Y recuerda que el cambio no surte efecto hasta que reinicias cada servicio y reconstruyes las imágenes de contenedor que llevan Java dentro.
6. Opción 2: sin actualizar, cuatro órdenes
Si hoy no puedes cambiar de versión, haz a mano lo mismo que hace el parche: retira del almacén de Java las cuatro raíces afectadas. No cambias de versión ni recompilas nada. Solo reinicias.
Linux o macOS, de Java 8 a Java 27. Hace una copia con nombre único y, solo si la copia sale bien, retira las raíces:
JH="/opt/java/jdk-21"
KS="$JH/lib/security/cacerts"
B=$(sudo mktemp "$KS.bak-$(date +%Y%m%d)-XXXXXX") && sudo cp "$KS" "$B" &&
for a in emsignrootcag1 emsignrootcag2 emsigneccrootcag3 comodoaaaca; do
sudo "$JH/bin/keytool" -delete -keystore "$KS" -storepass changeit -alias "$a [jdk]"
done
Windows, desde PowerShell abierto como administrador. Si la copia falla, no borra nada:
$JH = "C:\Program Files\Java\jdk-21"
$KS = "$JH\lib\security\cacerts"
try {
[IO.File]::Copy($KS, "$KS.bak-$(Get-Date -Format yyyyMMdd-HHmmss)", $false)
foreach ($a in "emsignrootcag1","emsignrootcag2","emsigneccrootcag3","comodoaaaca") {
& "$JH\bin\keytool" -delete -keystore $KS -storepass changeit -alias "$a [jdk]"
}
} catch { Write-Warning $_ }
Después, en la misma consola, lanza la comprobación. Con Java 11 o superior:
try {
Invoke-WebRequest https://cr.openjdk.org/~mr/CheckCerts.java -OutFile CheckCerts.java -ErrorAction Stop
& "$JH\bin\java" CheckCerts.java
} catch { Write-Warning $_ }
Con Java 8 a 10, o si ese Java no trae compilador, lanza este otro bloque de comprobación en su lugar. Necesita el javac de un JDK 8 o posterior:
try {
Invoke-WebRequest https://cr.openjdk.org/~mr/CheckCerts.java -OutFile CheckCerts.java -ErrorAction Stop
javac -source 8 -target 8 CheckCerts.java
if ($LASTEXITCODE -eq 0) { & "$JH\bin\java" -cp . CheckCerts }
} catch { Write-Warning $_ }
Cambia la ruta de la primera línea por tu java.home. changeit es la contraseña por defecto del almacén. Si keytool te sugiere usar la opción -cacerts, no pasa nada. Si dice que un alias no existe, la comprobación final te dirá si queda alguna raíz con otro nombre.
Reinicia los servicios Java. En Linux y macOS, repite la comprobación del punto 4. Debe decir No bad root certificates found.
Si una conexión legítima deja de funcionar, restaura la copia cacerts.bak-… sobre cacerts y reinicia. Pero ojo: así vuelves a confiar en esas raíces y reabres el riesgo. Úsalo solo para recuperar el servicio mientras actualizas Java o resuelves esa conexión.
7. Si tu Java viene de tu distribución Linux
Si instalaste Java con apt o dnf, normalmente usa el almacén del sistema y basta con actualizarlo. Hay una excepción importante en Debian y Ubuntu.
RHEL 8, 9 y 10, Fedora, Oracle Linux, Rocky y Alma (en RHEL 7 el paquete corregido aún está pendiente):
sudo dnf upgrade ca-certificates
Debian y Ubuntu: actualizar no basta, por un fallo antiguo de ca-certificates-java que no borra del almacén de Java lo que el sistema ya retiró. Hay que regenerarlo:
Antes de regenerar: esto borra las CA internas que alguien añadiera a mano con keytool a ese almacén. Las instaladas en /usr/local/share/ca-certificates vuelven solas. Si tenías alguna añadida a mano, vuelve a importarla desde la copia antes de reiniciar. Si un paso falla, el bloque se detiene.
sudo apt update &&
sudo apt install --only-upgrade ca-certificates ca-certificates-java &&
B=$(sudo mktemp /root/java-cacerts.bak-XXXXXX) && sudo cp -L /etc/ssl/certs/java/cacerts "$B" &&
sudo rm -f /etc/ssl/certs/java/cacerts &&
sudo update-ca-certificates --fresh
Después, reinicia los servicios Java y comprueba con CheckCerts. Si aún salen emSign ECC Root CA - G3 o AAA Certificate Services, tu paquete ca-certificates todavía no trae el arreglo.
8. Lo que este caso pide al cumplimiento
Si tu organización trabaja con el ENS, la ISO 27001, NIS2 o datos personales, esto no es solo un ajuste técnico. Es una prueba de que tu gestión de vulnerabilidades funciona de verdad.
- Inventario. Saber qué Java corre en servidores, contenedores, integración continua y aplicaciones de terceros que traen el suyo, que pueden recuperar su almacén original al actualizarse. Lo que no está inventariado no se parchea.
- Evidencia. Dejar registrado qué revisaste, qué cambiaste y cuándo. Es lo que esperan el ENS (op.exp.4), la ISO 27001 (control 8.8) y NIS2 (artículo 21).
- Versiones sin soporte. Un Java que ya no recibe parches es una deuda que este caso hace visible. Planifica el salto a Java 21 o 25.
- Posible brecha. Si sospechas que alguien interceptó tráfico con datos personales, valora si es una brecha que debes notificar en 72 horas (RGPD, artículo 33).
Preguntas frecuentes
¿Es tan grave como Log4Shell?
No. Log4Shell permitía ejecutar código en un servidor con una simple petición. Aquí el atacante tiene que estar en medio de la red para suplantar un servidor HTTPS ante tu aplicación Java. Es serio porque es difícil de detectar, pero exige una posición que no siempre está a su alcance.
Actualicé Java el 21 de octubre. ¿Estoy cubierto?
Solo en parte. Esa versión deja de confiar en los ocho intermedios conocidos. La del 24 de octubre, por ejemplo la 21.0.13.0.3, retira además cuatro raíces del almacén, entre ellas las dos relacionadas con esos intermedios. Instálala o aplica las órdenes de keytool, que no hacen daño si alguna raíz ya no está.
Mi aplicación está detrás de nginx o Apache. ¿Me afecta?
El proxy protege las conexiones que recibes, no las que tu aplicación abre hacia fuera. Si tu Java llama por HTTPS a pasarelas de pago, bancos, APIs o servicios de la Administración, esas conexiones siguen expuestas hasta que lo corrijas.
¿Retirar esas raíces puede romper algo?
Es el mismo cambio que hace el parche oficial de Oracle. Las cadenas actuales de Sectigo suelen terminar en USERTrust o en sus raíces nuevas, no en AAA, y en mis pruebas los destinos habituales siguieron funcionando. Aun así, algún servicio antiguo podría depender de ella, así que prueba tus conexiones críticas. Si restauras la copia, recuperas la conexión pero también la confianza en esas raíces.
Uso Java 23 u otra versión sin soporte. ¿Qué hago?
No te va a llegar parche. Aplica hoy la opción 2, que funciona en cualquier versión desde Java 8, y planifica el paso a una versión con soporte a largo plazo, como Java 21 o 25.
¿Y si mi Java corre en contenedores Docker?
Cada imagen lleva su propio Java y su propio almacén, así que actualizar el servidor no la corrige. Lo más limpio es reconstruirla sobre una imagen base ya corregida y comprobarla con CheckCerts. Si aún no la hay, añade al Dockerfile un paso RUN que ejecute keytool -delete -cacerts -storepass changeit con cada uno de los cuatro alias (desde Java 11) y vuelve a desplegar los contenedores.
¿Puedo activar la comprobación de revocación en lugar de retirar raíces?
Es otra vía que recoge OpenJDK, añadiendo -Dcom.sun.net.ssl.checkRevocation=true y -Dcom.sun.security.enableCRLDP=true al arranque. Pero añade consultas de red a las conexiones y, si la lista de revocación no llega, la conexión falla. Para el mínimo impacto, prefiero retirar las raíces.
Fuentes consultadas
Fecha de corte 25 de octubre de 2026. La situación evoluciona: revisa las fuentes oficiales antes de actuar.
- Oracle Security Alert CVE-2026-91403
- Oracle Security Alert CVE-2026-114820
- OpenJDK: Compromised Certificates and OpenJDK Java Runtimes
- OpenJDK Vulnerability Advisory 2026/10/21
- Oracle JDK 21: notas de versión consolidadas
- eMudhra Intermediate CA Compromise
- Mozilla Bugzilla 2083449: eMudhra private key compromise of intermediate certificates
- Red Hat: CVE-2026-91403
- GitHub Advisory GHSA-9h75-rf66-wh3r
¿No sabes qué Java tienes en producción?
Puedo inventariar vuestros runtimes Java, aplicar la corrección con vuelta atrás y dejaros la evidencia lista para ENS, ISO 27001 o NIS2.