Ответ
Клиент шифрует данные с помощью публичного ключа сервера, который содержится в сертификате сервера (X.509 сертификат). Этот сертификат клиент получает и проверяет во время фазы TLS handshake.
Принцип работы:
- Сервер отправляет клиенту свой сертификат.
- Клиент проверяет его подлинность (цепочку доверия, срок действия, доменное имя).
- Клиент извлекает из сертификата публичный ключ сервера.
- Сгенерированный симметричный сессионный ключ (или предмастер-секрет) шифруется этим публичным ключом. Расшифровать его может только сервер, обладающий соответствующим приватным ключом.
Пример извлечения публичного ключа из сертификата в 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) напрямую данными публичным ключом не шифруют. Он используется для безопасного обмена симметричным сессионным ключом (гибридное шифрование), которым затем шифруется весь трафик.