> Как происходит обмен сертификатами в HTTPS (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: VK

Стек: Go

> Пример ответа

Обмен сертификатами в HTTPS происходит на этапе TLS-рукопожатия (TLS handshake). В Go этот процесс автоматизирован стандартной библиотекой crypto/tls, но понимание деталей важно для отладки и настройки.

Основные шаги:

  1. Client Hello - клиент отправляет список поддерживаемых шифров, версий TLS и случайное число.

  2. Server Hello - сервер выбирает шифр и версию, отправляет свой сертификат (X.509) и случайное число.

  3. Проверка сертификата - клиент проверяет цепочку сертификатов до доверенного корневого центра (CA), срок действия, доменное имя (CN/SAN) и подпись.

  4. Обмен ключами - обычно через Diffie-Hellman (ECDHE) для обеспечения Perfect Forward Secrecy. Клиент генерирует предварительный ключ, шифрует его публичным ключом из сертификата сервера и отправляет обратно.

  5. Вычисление сессионного ключа - обе стороны независимо вычисляют симметричный ключ из общего секрета.

  6. Finished - зашифрованное сообщение для проверки, что рукопожатие прошло успешно.

Пример в Go (сервер):

GO
package main
import (
"crypto/tls"
"log"
"net/http"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("HTTPS работает!"))
})
server := &http.Server{
Addr: ":443",
Handler: mux,
TLSConfig: &tls.Config{
// Минимальная версия TLS 1.2
MinVersion: tls.VersionTLS12,
// Предпочтение серверных шифров
PreferServerCipherSuites: true,
},
}
// Сертификат и ключ должны быть в PEM-формате
log.Fatal(server.ListenAndServeTLS("cert.pem", "key.pem"))
}

Клиентская проверка (пример):

GO
import (
"crypto/tls"
"net/http"
)
func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{
// InsecureSkipVerify: true // Только для тестов!
},
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")
// ...
}

Важные нюансы:

  • Сертификат может быть самоподписанным (для разработки) или выпущенным CA.

  • В Go проверка цепочки сертификатов происходит автоматически, если не установлен InsecureSkipVerify.

  • Для mTLS (взаимная аутентификация) сервер также запрашивает сертификат клиента через ClientAuth: tls.RequireAndVerifyClientCert.

Понимание этого процесса помогает диагностировать ошибки вроде x509: certificate is valid for example.com, not localhost или проблемы с цепочкой доверия.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью