Какой сертификат клиент использует для шифрования данных перед отправкой на сервер по TLS?

«Какой сертификат клиент использует для шифрования данных перед отправкой на сервер по TLS?» — вопрос из категории Безопасность, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Клиент шифрует данные с помощью публичного ключа сервера, который содержится в сертификате сервера (X.509 сертификат). Этот сертификат клиент получает и проверяет во время фазы TLS handshake.

Принцип работы:

  1. Сервер отправляет клиенту свой сертификат.
  2. Клиент проверяет его подлинность (цепочку доверия, срок действия, доменное имя).
  3. Клиент извлекает из сертификата публичный ключ сервера.
  4. Сгенерированный симметричный сессионный ключ (или предмастер-секрет) шифруется этим публичным ключом. Расшифровать его может только сервер, обладающий соответствующим приватным ключом.

Пример извлечения публичного ключа из сертификата в Java:

// В рамках SSL-контекста
SSLSession session = sslSocket.getSession();
Certificate[] peerCertificates = session.getPeerCertificates();
X509Certificate serverCert = (X509Certificate) peerCertificates[0];
PublicKey serverPublicKey = serverCert.getPublicKey();
// serverPublicKey используется для шифрования данных для сервера

Важно: В современных протоколах (TLS 1.2/1.3) напрямую данными публичным ключом не шифруют. Он используется для безопасного обмена симметричным сессионным ключом (гибридное шифрование), которым затем шифруется весь трафик.