openjdk.ruOpenJDK на русском

JEP draft: TLS Support for the QUIC Transport (Preview)

Поддержка TLS для транспорта QUIC, Preview (предварительная версия)

AuthorsDaniel Jelinski, Alan Bateman
ОтветственныйDaniel Jelinski
ТипFeature
ОбластьSE
СтатусDraft
Компонентsecurity-libs / javax.net.ssl
Обсуждениеsecurity dash dev at openjdk dot org
ТрудоёмкостьL
ДлительностьM
Создан2026/05/05 09:34
Обновлён2026/09/17 14:49
Задача8383849

Аннотация

Расширить API javax.net.ssl, чтобы они поддерживали защиту транспорта QUIC. Так библиотеки и фреймворки, реализующие транспорт QUIC, смогут использовать реализацию Transport Layer Security (TLS) 1.3 из JDK, а приложения, использующие эти библиотеки и фреймворки, смогут настраивать TLS через стандартные API javax.net.ssl. Это API в статусе Preview.

Цели

  • Дать библиотекам и фреймворкам, реализующим QUIC, возможность использовать реализацию TLS 1.3 из JDK, чтобы выполнять рукопожатие TLS и получать секреты трафика, необходимые для защиты пакетов QUIC.

  • Дать приложениям, использующим библиотеки QUIC, возможность настраивать TLS с помощью тех же объектов SSLContext и SSLParameters, что используются для TLS поверх TCP.

  • Использовать новый API QUIC TLS в реализации HTTP/3 в HTTP Client из JDK.

Что не является целью

  • Предоставить реализацию QUIC не является целью.

  • Определить QUIC API общего назначения не является целью.

  • Поддержка QUIC 0-RTT не является целью.

Мотивация

QUIC — современный защищённый транспортный протокол, работающий поверх UDP. По сравнению с традиционными транспортами на основе TCP QUIC обеспечивает меньшую задержку установления соединения, улучшенное восстановление после потерь и управление перегрузкой, миграцию соединений и мультиплексированные потоки без блокировки начала очереди (head-of-line blocking).

HTTP/3 использует QUIC в качестве нижележащего транспортного протокола. По мере того как HTTP/3 всё шире внедряется в веб-сервисах, сетях доставки контента, облачной инфраструктуре и распределённых приложениях, библиотекам и фреймворкам Java всё чаще требуется поддержка HTTP/3 и QUIC. HTTP-серверам, в которые добавляется поддержка HTTP/3, приходится либо самим реализовывать QUIC, либо тесно интегрировать реализацию QUIC со своей реализацией HTTP/3. Такая интеграция охватывает управление соединениями и потоками и при этом позволяет HTTP-серверам управлять поведением протокола, настраивать управление перегрузкой и оптимизировать производительность.

QUIC также используется как транспорт для других протоколов, включая DNS и SMB, и его применяют новые протоколы, например Media Over QUIC.

QUIC использует TLS 1.3 для аутентификации и обмена ключами, как определено в RFC 9001. В отличие от TCP, в QUIC протокол TLS 1.3 встроен непосредственно в транспортный протокол. Поэтому реализации транспорта QUIC и реализации TLS 1.3 требуется тесная интеграция во время рукопожатия и на протяжении жизненного цикла ключей. Однако стандартные API Java для TLS были спроектированы для традиционных транспортов, таких как TCP, и не поддерживают напрямую схемы взаимодействия, которых требует QUIC.

Без такой поддержки реализациям QUIC приходится использовать нестандартные API или сторонние библиотеки TLS либо предоставлять собственные механизмы настройки TLS.

HTTP Client из JDK (JEP 517) использует внутреннюю реализацию QUIC, спроектированную специально для HTTP Client и тесно с ним интегрированную. Она интегрируется с реализацией TLS 1.3 из JDK через внутренние механизмы JDK, недоступные библиотекам и фреймворкам, реализующим QUIC.

Библиотекам и фреймворкам, реализующим QUIC, было бы полезно, если бы API javax.net.ssl можно было использовать для защиты транспорта QUIC. Тогда библиотеки и фреймворки могли бы использовать реализацию TLS 1.3 из JDK, а приложения — повторно использовать существующие SSLContext, SSLParameters, инфраструктуру управления ключами, управления доверием и провайдеров, уже применяемую для TLS поверх TCP.

Описание

Добавляется новый интерфейс QuicTLSAdapter для поддержки взаимодействия между TLS 1.3 и реализацией транспорта QUIC. Реализация QUIC передаёт QuicTLSAdapter при создании SSLEngine. Интерфейс определяет обратные вызовы для специфичных для QUIC взаимодействий с TLS, включая обмен транспортными параметрами QUIC, определение наборов шифров, поддерживаемых реализацией QUIC, передачу секретов трафика, используемых для защиты пакетов QUIC, и сообщение о сбоях рукопожатия.

package javax.net.ssl;

public interface QuicTLSAdapter {
    Set<String> getSupportedCipherSuites();
    ByteBuffer localQuicTransportParameters();
    void remoteQuicTransportParameters(ByteBuffer parameters) throws IOException;
    void deriveHandshakeReadSecrets(SecretKey secretKey, String cipherSuite)
            throws GeneralSecurityException;
    void deriveHandshakeWriteSecrets(SecretKey secretKey, String cipherSuite)
            throws GeneralSecurityException;
    void deriveApplicationReadSecrets(SecretKey secretKey, String cipherSuite)
            throws GeneralSecurityException;
    void deriveApplicationWriteSecrets(SecretKey secretKey, String cipherSuite)
            throws GeneralSecurityException;
    void cryptoError(int code, Exception closeReason);
}

В SSLContext добавляются два новых фабричных метода для создания SSLEngine, настроенного для использования с QuicTLSAdapter:

public final SSLEngine createSSLEngine(QuicTLSAdapter quicTLSAdapter);

public final SSLEngine createSSLEngine(String peerHost,
                                       int peerPort,
                                       QuicTLSAdapter quicTLSAdapter);

В SSLContextSpi добавляются два соответствующих метода:

protected SSLEngine engineCreateSSLEngine(QuicTLSAdapter quicTLSAdapter);

protected SSLEngine engineCreateSSLEngine(String host, int port,
                                          QuicTLSAdapter quicTLSAdapter);

Эти методы имеют ту же семантику, что и существующие методы createSSLEngine и engineCreateSSLEngine.

API QUIC TLS — это API в статусе Preview, по умолчанию отключённый

Чтобы использовать API QUIC TLS, необходимо включить Preview-API следующим образом:

  • Скомпилируйте программу с javac --release NN --enable-preview Main.java и запустите её с java --enable-preview Main; или
  • При использовании средства запуска программ из исходного кода запускайте программу с java --enable-preview Main.java; или
  • При использовании jshell запускайте его с jshell --enable-preview.

Интеграция рукопожатия

Во время рукопожатия QUIC TLS SSLEngine создаёт и принимает сообщения рукопожатия TLS, а транспорт QUIC передаёт эти сообщения в кадрах CRYPTO QUIC. QuicTLSAdapter служит посредником в специфичных для QUIC взаимодействиях между SSLEngine и транспортом QUIC, включая передачу секретов трафика, необходимых транспорту QUIC для получения ключей защиты пакетов.

Транспорт QUIC и SSLEngine взаимодействуют через QuicTLSAdapter, пока секреты трафика приложения не станут доступны в обоих направлениях. После этого SSLEngine больше не участвует.

Наборы шифров и транспортные параметры

Прежде чем согласовать набор шифров, SSLEngine получает наборы шифров, поддерживаемые QuicTLSAdapter. Так гарантируется, что согласованный набор шифров поддерживается и реализацией TLS 1.3, и реализацией транспорта QUIC.

Во время рукопожатия SSLEngine получает локальные транспортные параметры QUIC от QuicTLSAdapter и передаёт ему транспортные параметры QUIC другой стороны.

Альтернативы

Предоставить API для транспорта QUIC

В JDK есть внутренняя реализация QUIC для поддержки HTTP/3 в HTTP Client, но эта реализация приспособлена к нуждам HTTP Client. Обобщение реализации из JDK и её предоставление в виде поддерживаемого публичного QUIC API потребовали бы существенно больше инженерных усилий, чем интеграция TLS, предлагаемая этим JEP, включая значительную работу над поддержкой протокола и транспорта.

Вместо того чтобы предоставлять полный стек QUIC, JDK лучше предоставлять базовые возможности, необходимые реализациям QUIC, такие как специфичная для QUIC интеграция TLS и эффективная работа с сетью по UDP. Сосредоточившись на этих вспомогательных возможностях, JDK может поддерживать широкий спектр реализаций QUIC, позволяя библиотекам и фреймворкам глубоко интегрировать свои реализации QUIC и сохранять контроль над поведением протокола и производительностью.

Реализовать новый класс вместо повторного использования SSLEngine

SSLEngine спроектирован для TLS поверх традиционных транспортов, и часть его API неприменима к QUIC, а другие части полезны лишь в ограниченной мере. Новый класс мог бы предоставить более чистый API, приспособленный именно к нуждам QUIC.

Введение нового класса потребовало бы расширить SPI X509ExtendedKeyManager и X509ExtendedTrustManager методами, поддерживающими новый класс. Это осложнило бы взаимодействие, когда SSLContext использует KeyManager или TrustManager от другого провайдера. Повторное использование SSLEngine позволяет избежать этой проблемы и не требует изменений в существующих менеджерах ключей и доверия.

Включить поддержку QUIC 0-RTT

QUIC 0-RTT позволяет клиенту отправлять данные приложения, например HTTP-запросы, в первом пакете возобновлённого соединения. Это уменьшает задержку установления соединения за счёт использования ранее закэшированного состояния сессии.

Для поддержки QUIC 0-RTT сначала потребовалась бы поддержка TLS 0-RTT Data в реализации TLS из JDK. Введение специфичного для QUIC API 0-RTT сейчас создало бы риск несовместимости с будущим TLS 0-RTT API общего назначения.

Тестирование

Реализация HTTP/3 в HTTP Client из JDK (JEP 517) будет использовать новый API QUIC TLS, что обеспечит сквозное тестирование интеграции между QUIC и TLS 1.3.

Существующие тесты TLS будут расширены, чтобы охватить специфичное для QUIC поведение, включая выбор набора шифров, обмен транспортными параметрами, передачу секретов трафика и сбои рукопожатия.