Назад
2026/10/23
20 октября 2026 года стало известно, что закрытые ключи восьми промежуточных удостоверяющих центров (УЦ, CA) индийского УЦ eMudhra может восстановить кто угодно. Браузеры заблокировали эти сертификаты в тот же день, когда поступило сообщение о проблеме. Однако многие Java-приложения доверяют им до сих пор и будут доверять, пока кто-нибудь не обновит JDK или не изменит его truststore.
21 октября 2026 года BellSoft опубликовала результаты тестов, показывающие, что многие среды выполнения Java по-прежнему принимают эти сертификаты. В этой статье мы кратко излагаем эти выводы, которые подтвердили в собственных тестах, и объясняем, почему Java затронута, а браузеры нет, как проверить ваши системы и что делать.
Главное
- Скомпрометированы ключи восьми промежуточных УЦ eMudhra. Владелец любого из них может выпустить сертификат для любого имени хоста, и клиент, доверяющий цепочке, его примет.
- Браузеры их блокируют, но Java использует собственный truststore и по умолчанию не проверяет ни отзыв сертификатов, ни Certificate Transparency.
- Сборки JDK от нескольких поставщиков по-прежнему доверяют некоторым или всем затронутым цепочкам, в том числе в образах контейнеров.
- Пока ваш поставщик не выпустит исправленный JDK, удалите два затронутых корневых сертификата из truststore, предварительно протестировав изменение. Второй вариант — проверка отзыва.
Что произошло
eMudhra неправильно сгенерировала закрытые ключи восьми своих промежуточных сертификатов УЦ, поэтому любой может восстановить их из открытых сертификатов. Это возможно с момента выпуска промежуточных сертификатов в апреле 2025 года.
17 октября 2026 года автор сообщения доказал наличие проблемы: подписал фразу «We have a problem here» каждым из восьми ключей и отправил подписи в корневые программы браузеров. Подробности стали публичными 20 октября.
- Шесть промежуточных УЦ выпускают TLS-сертификаты: DV-, OV- и EV-УЦ eMudhra для TLS поколений G3B и G3C.
- Два промежуточных УЦ выпускают сертификаты для подписи кода.
- Каждый промежуточный сертификат существует в двух вариантах: подписанный корневым сертификатом eMudhra emSign и перекрёстно подписанный корневым сертификатом Sectigo
AAA Certificate Services. В truststore JDK цепочки заканчиваются на одном из двух корневых сертификатов:emSign ECC Root CA - G3(через перекрёстную подпись) илиAAA Certificate Services.
Firefox и Chrome блокируют эти промежуточные сертификаты с 17 октября, Apple — с 19 октября, Microsoft — с 20 октября. eMudhra отозвала все восемь 18 и 19 октября с причиной CA_COMPROMISE. Дистрибутивы Linux выпустили обновлённые пакеты сертификатов УЦ.
Каковы последствия
Владелец любого из этих ключей может создать сертификат для любого имени хоста — например, вашего банка, облачного провайдера или вашего собственного API-шлюза. Клиент, доверяющий цепочке, его примет. Если у злоумышленника есть ещё и возможность перехватывать трафик, например через скомпрометированную сеть или изменённую DNS-запись, он сможет:
- читать и изменять трафик между Java-приложением и вызываемыми им сервисами, включая пароли, API-ключи и токены;
- выдавать себя за репозитории пакетов, серверы обновлений или API партнёров;
- с помощью двух промежуточных УЦ для подписи кода подписывать код так, будто он получен от доверенного издателя.
Эти промежуточные сертификаты никогда не появлялись в журналах Certificate Transparency (CT), поэтому браузеры, требующие CT, через них атаковать было нельзя. Использовались ли ключи против клиентов, которые не проверяют CT, пока неизвестно. Java — один из таких клиентов.
Почему Java по-прежнему доверяет этим сертификатам
Mozilla, Google, Apple и Microsoft распространили блокировку через собственные каналы, такие как OneCRL, CRLite и CRLSets. Стандартная реализация TLS в JDK не читает ни один из них. Java остаётся уязвимой из-за трёх настроек по умолчанию:
- Собственный truststore. Если приложение не задаёт
javax.net.ssl.trustStore, Java доверяет корневым сертификатам из$JAVA_HOME/lib/security/jssecacerts, если этот файл существует, а иначе — из$JAVA_HOME/lib/security/cacerts. Поставляемый вендоромcacertsне получает ни блок-листов браузеров, ни обновлений сертификатов УЦ операционной системы. Он меняется, только если его отредактирует администратор или заменит обновление JDK. - Нет проверки отзыва. Java не проверяет отзыв сертификатов, пока вы это не включите (
com.sun.net.ssl.checkRevocationпо умолчанию равен false), поэтому при стандартной конфигурации отзыв со стороны УЦ не виден. - Нет Certificate Transparency. JDK не требует CT, поэтому защита, которая уберегла пользователей браузеров, здесь не работает.
На странице с раскрытием информации перечислены двенадцать тестовых хостов — по одному на каждую комбинацию промежуточного и корневого сертификата. BellSoft проверила их в Linux 21 октября, а мы повторили тест 23 октября:
| Протестированная среда | Доверенные тестовые хосты |
|---|---|
| Liberica JDK 21.0.10 | 12 из 12 |
| Liberica JDK 8u504 (образ контейнера) | 12 из 12 |
| Liberica JDK 21.0.12.1 (образ контейнера) | 12 из 12 |
| Eclipse Temurin 25.0.4.1 | 6 из 12 (только корень eMudhra) |
| Eclipse Temurin 21.0.12.1 (образ контейнера, наш тест) | 6 из 12 (только корень eMudhra) |
| Arch Linux OpenJDK 27 (системное хранилище УЦ) | 6 из 12 (только корень eMudhra) |
Разница — в корневом сертификате Sectigo. Mozilla уже удалила AAA Certificate Services, а truststore в Temurin и Arch Linux формируются на основе списка Mozilla, поэтому открыт только путь через eMudhra. В truststore Liberica JDK этот корневой сертификат по-прежнему есть, поэтому открыты оба пути.
Какие системы проверить
- Автономные JDK, распакованные из архива вендора или установленные его установщиком. Они используют собственный
cacerts. - Образы контейнеров, содержащие JDK. В образах, которые проверяла BellSoft, обновление пакета
ca-certificatesоперационной системы не менялоcacertsв JDK. Не помогала и загрузка более нового базового образа: проверенный образ Liberica от 21 октября по-прежнему доверял всем двенадцати тестовым хостам. - Приложения с собственным truststore, заданным через
javax.net.ssl.trustStore, в конфигурации сервера приложений или внутри самого приложения. Проверьте, содержат ли они эти два корневых сертификата. - OpenJDK из пакетов дистрибутива. Проверьте, куда указывает
cacerts. Если он связан с системным хранилищем УЦ (в Arch Linux это символическая ссылка на/etc/ca-certificates/extracted/java-cacerts.jks), проблему устраняет обновлениеca-certificatesв дистрибутиве. Версии исправленных пакетов перечислены на странице с раскрытием информации.
Как проверить JDK
Сначала найдите два корневых сертификата в truststore. Имена алиасов у вендоров различаются (в Liberica JDK — emsigneccrootcag3 [jdk], в Temurin — cn_emsign_ecc_root_ca__g3,...), поэтому ищите по субъекту сертификата. Существует ещё несколько корневых сертификатов emSign; затронут только emSign ECC Root CA - G3. В JDK 9 и новее:
keytool -list -v -cacerts -storepass changeit | grep -E '^Alias name:|^Owner:' | grep -B1 -E '^Owner: CN=(emSign ECC Root CA - G3|AAA Certificate Services),'
У keytool из Java 8 нет параметра -cacerts, а truststore находится в каталоге jre/:
keytool -list -v -keystore "$JAVA_HOME/jre/lib/security/cacerts" -storepass changeit | grep -E '^Alias name:|^Owner:' | grep -B1 -E '^Owner: CN=(emSign ECC Root CA - G3|AAA Certificate Services),'
Для каждого совпадения выводится имя алиаса, а за ним — субъект сертификата. Запишите имена алиасов: они понадобятся для исправления.
Затем проверьте реальные подключения. Эта небольшая программа подключается ко всем двенадцати тестовым хостам и работает в Java 8 и всех последующих версиях:
import java.net.URI;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLHandshakeException;
public class Check {
public static void main(String[] args) {
for (String level : new String[]{"dv", "ov", "ev"})
for (String gen : new String[]{"g3b", "g3c"})
for (String via : new String[]{"", "-aaa"}) {
String host = level + "-" + gen + via + "-emudhra.we-have-a-problem.com";
try {
HttpsURLConnection c = (HttpsURLConnection) URI.create("https://" + host).toURL().openConnection();
c.setConnectTimeout(10000);
c.setReadTimeout(10000);
c.connect();
c.disconnect();
System.out.println("TRUSTED " + host);
} catch (SSLHandshakeException e) {
System.out.println("TLS_REJECTED " + host);
} catch (Exception e) {
System.out.println("ERROR " + host + " (" + e + ")");
}
}
}
}
В JDK 11 и новее запустите её командой java Check.java. В Java 8 или если установлена только JRE сначала скомпилируйте её командой javac Check.java (при необходимости на машине с JDK), а затем выполните java Check. Строка TRUSTED означает, что этот JDK принимает скомпрометированный промежуточный сертификат. ERROR означает, что хост недоступен, и это ничего не доказывает ни в ту, ни в другую сторону. Выполняйте проверку с тем же JDK и теми же настройками truststore, что и у вашего приложения, в том числе внутри контейнеров.
Как это исправить
1. Удалите два корневых сертификата (рекомендуется до выхода исправленного JDK)
Это те же два корневых сертификата, которым, согласно странице с раскрытием информации, пользователям Linux и macOS следует перестать доверять. Выполните команды от имени пользователя, которому принадлежит JDK, указав имена алиасов, найденные при проверке. Например, для Liberica JDK:
keytool -delete -cacerts -storepass changeit -alias "comodoaaaca [jdk]"
keytool -delete -cacerts -storepass changeit -alias "emsigneccrootcag3 [jdk]"
В Java 8 замените -cacerts на -keystore "$JAVA_HOME/jre/lib/security/cacerts". Если в вашем truststore есть только один из двух корневых сертификатов, как в Temurin, удалите только его.
Если изменить установку JDK нельзя, отредактируйте копию и укажите её JVM:
cp "$JAVA_HOME/lib/security/cacerts" ./trimmed-cacerts
keytool -delete -keystore ./trimmed-cacerts -storepass changeit -alias "comodoaaaca [jdk]"
keytool -delete -keystore ./trimmed-cacerts -storepass changeit -alias "emsigneccrootcag3 [jdk]"
java -Djavax.net.ssl.trustStore=./trimmed-cacerts -Djavax.net.ssl.trustStorePassword=changeit -jar app.jar
В наших тестах оба способа привели к тому, что Liberica JDK 8 и 21 отклонили все двенадцать тестовых хостов, а обычные сайты, такие как sectigo.com и github.com, по-прежнему открывались.
Для образов контейнеров удаляйте корневые сертификаты на этапе сборки, чтобы каждый новый образ уже был исправлен:
FROM bellsoft/liberica-runtime-container:jdk-21-musl
RUN keytool -delete -cacerts -storepass changeit -alias "comodoaaaca [jdk]" \
&& keytool -delete -cacerts -storepass changeit -alias "emsigneccrootcag3 [jdk]"
Для distroless-образов и образов, работающих не от root, нужны два изменения: в них нет оболочки, поэтому используйте exec-форму RUN с одной командой на строку; и они работают от непривилегированного пользователя, поэтому переключитесь на USER root для правки, а затем вернитесь к обычному пользователю образа.
Совет: удаление корневого сертификата затрагивает больше, чем блокировка восьми промежуточных. Легитимный сервер, цепочка которого заканчивается только на одном из этих корневых сертификатов, перестанет работать. Протестируйте сервисы, которые вызывает ваше приложение, прежде чем развёртывать изменение, и повторяйте проверку после каждого обновления JDK, потому что обновление или переустановка может вернуть исходный cacerts.
2. Включите проверку отзыва (необязательно)
eMudhra отозвала все восемь промежуточных сертификатов, поэтому JVM, проверяющая отзыв, отклонит их без каких-либо изменений в truststore. Включите точки распространения CRL и OCSP:
echo 'ocsp.enable=true' > revocation.security
java -Dcom.sun.net.ssl.checkRevocation=true \
-Dcom.sun.security.enableCRLDP=true \
-Djava.security.properties=revocation.security \
-jar app.jar
В наших тестах это привело к отклонению всех двенадцати тестовых хостов в Liberica JDK 8 и 21, а также в Temurin 21. Однако при этом меняется проверка каждого сертификата. JVM выполняет запросы OCSP или CRL при проверке цепочки, и рукопожатие может завершиться ошибкой, если статус отзыва определить не удаётся. Прежде чем включать это глобально, проверьте, доступны ли респондеры с ваших серверов, какую задержку они добавляют и как ведёт себя система при сбоях. Используйте этот вариант, если проверка отзыва у вас уже включена, или вместе с удалением корневых сертификатов.
3. Обновите JDK, когда появятся исправленные сборки
BellSoft сообщила, что готовит обновления Liberica JDK, удаляющие эти корневые сертификаты. Следите за бюллетенями безопасности своего поставщика JDK. Когда обновление выйдет, убедитесь по примечаниям к выпуску, что оно касается сертификатов eMudhra, установите его, пересоберите образы контейнеров и снова выполните проверку. Более новый номер версии сам по себе ничего не доказывает.
После исправления: оцените, были ли вы под угрозой
Ключи можно было восстановить около восемнадцати месяцев, поэтому исправление закрывает дверь, но не говорит, воспользовался ли ею кто-нибудь. Для систем, передающих учётные данные или конфиденциальные данные, поищите в журналах TLS-инспекции, прокси и конечных устройств сертификаты, выпущенные восемью промежуточными УЦ eMudhra. Если найдёте что-то подозрительное, смените затронутые учётные данные.
В долгосрочной перспективе относитесь к truststore как к зависимостям: знайте, где находится каждый из них, кто его обновляет и как быстро изменение доходит до продакшена. Этот инцидент показывает, что обновления браузера недостаточно, если ваши серверы используют собственную копию списка доверия.
Нужна помощь? LOGIQ предоставляет поддержку OpenJDK и Linux, включая установку исправлений безопасности. Если вам нужна помощь в поиске всех JDK и truststore в вашей среде или в безопасном развёртывании исправления, свяжитесь с нами.
Дополнительные материалы
- eMudhra Intermediate CA Compromise: страница с раскрытием информации, тестовыми хостами и версиями исправленных пакетов
- BellSoft: Distrusting compromised eMudhra intermediates in Java
Global
Japan
Korea
China
Taiwan
Vietnam
Thailand
Indonesia
Portugal
Spain
France
Germany
Egypt