> Для чего нужны центры сертификации и чем самоподписанные сертификаты отличаются от выданных центрами (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: VK
Стек: Go
> Пример ответа
Короткий ответ
Центры сертификации (CA) - это доверенные третьи стороны, которые подтверждают принадлежность публичного ключа конкретному субъекту, подписывая его сертификат. Самоподписанный сертификат - это сертификат, который субъект подписывает своим же ключом, без внешнего подтверждения. Разница в цепочке доверия: для CA клиент доверяет через предустановленные корневые сертификаты, для самоподписанного - только если клиент явно добавил его в доверенные. На практике CA используются в публичных системах, самоподписанные - во внутренних или для тестов.
Подробное объяснение
Сертификат X.509 - это структура данных, связывающая публичный ключ с идентификатором (домен, организация, человек) и подписанная некоторым ключом. Подпись гарантирует целостность и аутентичность содержимого.
Центр сертификации - это организация, которая:
- выпускает сертификаты после проверки заявителя (domain validation, organization validation, extended validation);
- подписывает их своим приватным ключом;
- поддерживает CRL (certificate revocation list) и OCSP (online certificate status protocol) для отзыва;
- управляет сроком действия и иерархией (root CA → intermediate CA → leaf).
Клиент (браузер, сервер, приложение) доверяет CA, потому что корневой сертификат CA предустановлен в доверенное хранилище операционной системы или приложения. При проверке клиент строит цепочку от leaf-сертификата до корневого, проверяя подписи на каждом уровне, срок действия, отзыв и имя.
Самоподписанный сертификат - это сертификат, где issuer и subject совпадают, и подпись сделана собственным приватным ключом. Он не входит ни в какую цепочку доверия, кроме самого себя. Клиент не может проверить его валидность без явного добавления в доверенные хранилище. Это создает риск MITM (man-in-the-middle), если клиент просто игнорирует предупреждение.
Ключевые отличия:
- доверие: CA - через предустановленные корни, самоподписанный - через ручное добавление;
- проверка подлинности: CA проверяет заявителя, самоподписанный - никто не проверяет;
- отзыв: CA поддерживает CRL/OCSP, для самоподписанного отзыв не имеет смысла;
- срок жизни: CA обычно выпускает на 1-2 года, самоподписанный - на любой срок;
- стоимость: CA платный (или бесплатный Let's Encrypt), самоподписанный - бесплатный.
На практике
В Go работа с сертификатами идет через crypto/tls, crypto/x509 и crypto/x509/pkix.
Для сервера с самоподписанным сертификатом:
- клиент должен либо добавить сертификат в
RootCAsвtls.Config, либо использоватьInsecureSkipVerify: true(крайне не рекомендуется в production); - для внутренних сервисов (например, между микросервисами в закрытой сети) самоподписанные сертификаты допустимы, если управление доверием автоматизировано (например, через внутренний CA или секреты).
Для публичного API или веб-сервиса обязательно использовать CA (Let's Encrypt, AWS Certificate Manager, внутренний корпоративный CA), потому что клиенты (браузеры, мобильные приложения) не будут доверять самоподписанному.
В Go при создании tls.Config для сервера обычно указывают Certificates (leaf + chain), а для клиента - RootCAs. При использовании CA-выданного сертификата цепочка включает промежуточные сертификаты, которые сервер должен отправлять клиенту.
Пример кода
GO// Создание самоподписанного сертификата в Gopackage mainimport ("crypto/ecdsa""crypto/elliptic""crypto/rand""crypto/x509""crypto/x509/pkix""encoding/pem""math/big""os""time")func main() {priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)tmpl := x509.Certificate{SerialNumber: big.NewInt(1),Subject: pkix.Name{CommonName: "localhost",},NotBefore: time.Now(),NotAfter: time.Now().Add(365 * 24 * time.Hour),KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},DNSNames: []string{"localhost"},}derBytes, _ := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)certOut, _ := os.Create("cert.pem")pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})certOut.Close()keyOut, _ := os.Create("key.pem")keyBytes, _ := x509.MarshalECPrivateKey(priv)pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes})keyOut.Close()}
GO// Клиент с доверием к самоподписанному сертификатуpackage mainimport ("crypto/tls""crypto/x509""io/ioutil""log""net/http")func main() {caCert, _ := ioutil.ReadFile("cert.pem")caCertPool := x509.NewCertPool()caCertPool.AppendCertsFromPEM(caCert)client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{RootCAs: caCertPool,},},}resp, err := client.Get("https://localhost:8443")if err != nil {log.Fatal(err)}defer resp.Body.Close()}
Как отвечать на собеседовании
Начни с определения CA и его роли в PKI. Затем четко сформулируй разницу в модели доверия: CA - это предустановленный корень, самоподписанный - ручное доверие. Приведи примеры, когда что использовать: публичный API - CA, внутренний сервис - самоподписанный или внутренний CA. Упомяни про цепочку сертификатов, intermediate CA и проверку отзыва. Если спросят про Go, покажи, как настроить tls.Config для клиента с кастомным RootCAs и почему InsecureSkipVerify - это плохо. Не углубляйся в криптографию, если не просят.
Что проверяет интервьюер
- понимание модели доверия PKI, а не просто заученных терминов;
- умение объяснить, почему самоподписанный сертификат небезопасен для публичных систем;
- знание практических аспектов: цепочка, отзыв, срок действия;
- для Go - умение работать с
crypto/tlsиcrypto/x509, пониманиеRootCAsиInsecureSkipVerify; - способность выбрать правильный подход под задачу (внутренний vs внешний сервис).
Типичные ошибки
- утверждение, что самоподписанный сертификат "небезопасен" сам по себе - он небезопасен только из-за отсутствия доверия;
- предложение использовать
InsecureSkipVerify: trueкак решение - это отключает проверку полностью и открывает MITM; - игнорирование промежуточных сертификатов - сервер должен отправлять всю цепочку, иначе клиент не сможет построить путь до корня;
- путаница между самоподписанным и self-signed CA (внутренний CA тоже может быть самоподписанным, но он используется для подписи других сертификатов);
- забывание про отзыв сертификатов - для CA это критично, для самоподписанных - не применимо.
> Похожие задачи по backend
Что такое table expressions в SQL?
Что такое CSRF и как определить поддельный запрос
Что такое MITM (man-in-the-middle) атака и как с ней бороться
Стоит ли кэшировать пустые результаты запросов к базе данных
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью