Все уроки
Основы вебаСредний10 мин чтенияВ моём стеке

HTTPS и TLS

Рукопожатие, сертификаты, Let's Encrypt и HSTS — по практическим шагам.

  • TLS 1.3
  • Certificates
  • Let's Encrypt
  • HSTS
  • Origin certificates
Шаг 1/5
Браузер хочет поговорить с example.com. В Wi-Fi кафе подслушивает шпион. Классика.

За 30 секунд

HTTPS — это HTTP, передаваемый внутри TLS, зашифрованного и аутентифицированного туннеля. TLS гарантирует, что никто не сможет прочитать или изменить трафик, а сертификат доказывает, что вы действительно общаетесь с example.com. С Let's Encrypt сертификаты бесплатны и продлеваются автоматически, поэтому каждый сайт должен работать только по HTTPS.

Почему я это использую

  • У меня везде HTTPS с автоматически продлеваемыми сертификатами Let's Encrypt; это часть моего базового набора безопасности для каждого сервера.
  • Логины, платежи и персональные данные в моих продуктах никогда не должны передаваться открытым текстом.
  • Браузеры помечают HTTP-страницы как небезопасные, а многие современные возможности (service worker'ы, геолокация, HTTP/2 в браузерах) требуют HTTPS.
  • Проблемы с сертификатами мгновенно роняют сайты, поэтому их понимание экономит много нервных часов.

Как это работает

01Что даёт TLS

TLS (Transport Layer Security, преемник SSL) обеспечивает три вещи. Конфиденциальность: трафик зашифрован, поэтому человек в той же Wi-Fi-сети видит только бессмыслицу. Целостность: любое изменение по пути обнаруживается. Аутентификацию: сервер подтверждает свою личность сертификатом, подписанным доверенным центром. Аналогия: запечатанный конверт с защитой от вскрытия, который доставляет курьер, проверивший паспорт получателя. TLS 1.3 (RFC 8446) — текущая версия, TLS 1.2 всё ещё допустим; SSL 3.0, TLS 1.0 и TLS 1.1 устарели, и их нужно отключить. Учтите: HTTPS скрывает пути, заголовки и тела, но доменное имя всё равно видно через DNS и поле SNI, если не используется Encrypted Client Hello.

02Рукопожатие TLS 1.3

Рукопожатие занимает один круговой путь. Браузер отправляет ClientHello: поддерживаемые наборы шифров, случайное значение, hostname (SNI), поддерживаемые протоколы (ALPN, например h2) и key share — свою половину эфемерного обмена Диффи — Хеллмана (обычно X25519, а в современных браузерах часто гибрид с постквантовым ML-KEM). Сервер отвечает ServerHello и своим key share; теперь обе стороны вычисляют один и тот же секрет, ни разу не передав его. Всё дальнейшее зашифровано: сервер отправляет цепочку сертификатов, подпись CertificateVerify, доказывающую владение закрытым ключом, и Finished. Браузер проверяет сертификат и отправляет свой Finished вместе с первым HTTP-запросом. Поскольку ключи эфемерные, украденный ключ сервера не позволит расшифровать прошлый трафик (forward secrecy). Возобновлённые сессии могут даже отправлять данные сразу (0-RTT), но с риском повторного воспроизведения.

bash
# See the negotiated version, cipher and certificate chain
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null
# Only accept TLS 1.3 to test support
openssl s_client -connect example.com:443 -servername example.com -tls1_3 </dev/null

03Сертификаты и цепочка доверия

Сертификат связывает открытый ключ с одним или несколькими hostname'ами (в поле Subject Alternative Name) на ограниченный срок и подписан центром сертификации (CA). Браузеры и операционные системы поставляются со списком доверенных корневых CA. Корневые CA редко подписывают сертификаты сайтов напрямую; они подписывают промежуточные CA, которые и подписывают ваш конечный (leaf) сертификат. Поэтому сервер должен отправлять leaf вместе с промежуточными (полную цепочку), а браузер строит путь до корневого CA, которому доверяет. Типы проверки: DV (проверка домена, автоматическая, её использует почти каждый), OV и EV (проверка организации, сегодня в браузерах никакой видимой пользы). Wildcard-сертификаты (*.example.com) покрывают один уровень поддоменов. Все публичные сертификаты записываются в журналы Certificate Transparency, поэтому можно увидеть каждый сертификат, выпущенный для вашего домена. Сроки действия сокращаются: отраслевой максимум снижается до 200 дней в 2026 году и до 47 дней в 2029 году, так что автоматизация обязательна.

04Let's Encrypt и certbot

Let's Encrypt — бесплатный автоматизированный CA, работающий по протоколу ACME. certbot доказывает, что вы контролируете домен, обычно через проверку HTTP-01 (отдаёт токен по пути /.well-known/acme-challenge/ на порту 80) или DNS-01 (TXT-запись, обязательна для wildcard). Установите его, запросите сертификат через плагин nginx — и он сам отредактирует конфигурацию nginx. Пакеты устанавливают systemd-таймер, который пытается продлить сертификат дважды в день и продлевает, когда срок подходит к концу. Всегда проверяйте продление с --dry-run и добавляйте deploy hook, чтобы nginx перезагружался с новым сертификатом. Сегодня сертификаты Let's Encrypt по умолчанию выдаются на 90 дней, уже доступны более короткие варианты на 45 дней, а срок по умолчанию снизится до 64 дней в 2027 году и до 45 дней в 2028-м, так что никогда не полагайтесь на ручное продление.

bash
sudo apt update && sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# Renewal is automatic; verify the timer and do a test run
systemctl list-timers | grep certbot
sudo certbot renew --dry-run
# Reload nginx after each successful renewal
sudo certbot renew --deploy-hook "systemctl reload nginx" --dry-run
sudo certbot certificates

05Хорошая TLS-конфигурация nginx и HSTS

Перенаправляйте весь HTTP на HTTPS, разрешайте только TLS 1.2 и 1.3 и доверьте выбор шифров современным настройкам по умолчанию. Mozilla SSL Configuration Generator даёт актуальные настройки для каждого сервера. HSTS (Strict-Transport-Security) велит браузерам использовать для вашего домена только HTTPS в течение max-age секунд, даже если кто-то вводит http:// или переходит по старой ссылке; это блокирует атаки SSL stripping. Внедряйте его осторожно: начните с короткого max-age, добавляйте includeSubDomains, только когда HTTPS есть на каждом поддомене, и отправляйте домен в браузерный preload-список (с флагом preload) только когда уверены, потому что удаление занимает месяцы. Если вы за Cloudflare в режиме Full (strict), тот же сертификат на origin покрывает второй участок.

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}
server {
    listen 443 ssl;
    http2 on;
    server_name example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:10m;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

06Частые ошибки SSL и как их исправить

NET::ERR_CERT_DATE_INVALID или «certificate has expired»: продление не сработало; проверьте логи certbot, таймер и доступность порта 80 для HTTP-01. ERR_CERT_COMMON_NAME_INVALID: сертификат не покрывает этот hostname, часто не хватает www; перевыпустите сертификат со всеми именами. «unable to get local issuer certificate» в curl, на Android или в Node-клиентах, когда браузеры работают: сервер отдаёт только leaf без цепочки; используйте fullchain.pem. ERR_SSL_VERSION_OR_CIPHER_MISMATCH: включены только старые протоколы или нет сертификата для этого SNI-имени. Mixed content: HTTPS-страница загружает скрипты или изображения по http://; исправьте URL или добавьте upgrade-insecure-requests в CSP. Ошибки HSTS, которые нельзя пропустить: сертификат недействителен на домене с HSTS; исправьте сертификат. За Cloudflare ошибки 525 и 526 — это те же проблемы на стороне origin.

bash
# Expiry dates and names covered
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates -subject -ext subjectAltName
sudo journalctl -u certbot --since "7 days ago"
sudo nginx -t && sudo systemctl reload nginx

Когда применять

  • Каждый публичный сайт, API и админка — без исключений.
  • Внутренние сервисы, передающие учётные данные или персональные данные, даже в частных сетях.
  • Между CDN и вашим origin (режим Full (strict)).

Когда не стоит

  • Не завершайте TLS в коде приложения, когда nginx или балансировщик нагрузки могут сделать это проще.
  • Не используйте самоподписанные сертификаты для публичных сайтов; берите Let's Encrypt или origin-сертификат за CDN.

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

  • Cloudflare Origin CA

    Бесплатные долгоживущие сертификаты, которым доверяет только Cloudflare, — для участка от edge до origin.

  • Caddy

    Веб-сервер, который сам получает и продлевает сертификаты без дополнительных инструментов.

  • acme.sh / lego

    Лёгкие ACME-клиенты, удобные для DNS-01 и нестандартных конфигураций.

  • Управляемые сертификаты

    AWS ACM, балансировщики нагрузки и PaaS-платформы сами занимаются выпуском и продлением.

Лучшие практики

  1. Автоматизируйте выпуск и продление, проверяйте через --dry-run и мониторьте сроки действия.
  2. Отдавайте полную цепочку (fullchain.pem), а не только leaf-сертификат.
  3. Включайте только TLS 1.2 и 1.3; следуйте профилю intermediate от Mozilla.
  4. Перенаправляйте HTTP на HTTPS через 301 и добавляйте HSTS после проверки всех поддоменов.
  5. Защищайте закрытые ключи строгими правами на файлы и никогда не коммитьте их.
  6. Добавьте CAA-запись со списком CA, которыми вы реально пользуетесь.

Частые ошибки

  • Продлевать вручную и забыть — сайт падает в день истечения срока.
  • Полностью закрыть порт 80, из-за чего ломается продление через HTTP-01.
  • Не отдавать промежуточные сертификаты, из-за чего часть клиентов падает, хотя десктопные браузеры работают.
  • Включить HSTS preload до того, как каждый поддомен поддерживает HTTPS.
  • Оставлять в шаблонах и базе данных URL с http://, из-за чего возникает mixed content.

Глубже

07Отзыв сертификатов и почему сроки жизни сокращаются

Если приватный ключ утёк, сертификату должны перестать доверять ещё до истечения срока. У обоих классических инструментов есть проблемы. CRL — это списки отозванных серийных номеров, которые могут сильно разрастаться. OCSP позволяет клиенту спросить CA об одном сертификате, но раскрывает CA, какие сайты посещает пользователь, добавляет задержку, а браузеры делают soft-fail, когда responder недоступен, так что атакующий, заблокировавший его, выигрывает. OCSP stapling, при котором сервер прикладывает подписанный статус, частично это исправил. Let's Encrypt закрыл свой OCSP-сервис в 2025 году и теперь публикует только CRL, а браузеры рассылают клиентам компактные наборы отзывов, собранные из CRL. Однако главный ответ индустрии — короткие сроки жизни: украденный ключ от 47-дневного сертификата полезен неделями, а не год. Это и есть настоящая причина сокращения максимального срока действия.

08Типы ключей, cipher suites и постквантовый обмен ключами

Ключ вашего сертификата — либо RSA (2048 бит — обычный минимум), либо ECDSA (P-256). Ключи ECDSA меньше, а подписи быстрее, что сокращает handshake; у RSA самая широкая поддержка среди очень старых клиентов. nginx может отдавать оба сразу и выбирать для каждого клиента. В TLS 1.3 всего несколько cipher suites, все AEAD (AES-GCM, ChaCha20-Poly1305), и по умолчанию они в порядке. Для TLS 1.2 следуйте профилю intermediate от Mozilla, который оставляет только обмен ключами ECDHE с AEAD-шифрами. Обмен ключами переходит на постквантовые гибриды: X25519MLKEM768 сочетает классический X25519 с ML-KEM, так что записанный трафик останется защищённым даже от будущих квантовых компьютеров. Современные браузеры его предлагают; в nginx для него нужен OpenSSL 3.5 или новее, а указание этой группы на старом OpenSSL не даст nginx запуститься.

nginx
# Dual certificates: modern clients get ECDSA, older ones RSA
ssl_certificate     /etc/letsencrypt/live/example.com-ecdsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com-ecdsa/privkey.pem;
ssl_certificate     /etc/letsencrypt/live/example.com-rsa/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com-rsa/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# Only with OpenSSL 3.5+:
# ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1;

09ACME в деталях: challenge, ARI и rate limit

ACME-клиент создаёт ключ аккаунта, оформляет заказ на набор имён, проходит по одному challenge для каждого имени, отправляет запрос на подпись сертификата и скачивает сертификат. HTTP-01 требует, чтобы порт 80 был доступен на каждом сервере, отвечающем за имя, поэтому за балансировщиком токен должны отдавать все узлы, иначе валидация будет падать случайным образом. DNS-01 работает для wildcard и приватных серверов, но API-токен, редактирующий DNS, очень мощный, поэтому ограничьте его одной зоной или делегируйте _acme-challenge в отдельную зону. TLS-ALPN-01 проверяет на порту 443. ACME Renewal Information (ARI, RFC 9773) позволяет CA подсказывать клиентам, когда продлевать, например раньше при массовом отзыве; certbot поддерживает это с версии 4.1. Let's Encrypt также применяет rate limit, например недельный лимит на сертификаты для одного зарегистрированного домена и на дубликаты, поэтому тестируйте на staging-окружении.

bash
# Practise against staging first (no rate-limit pain)
sudo certbot certonly --nginx --staging -d example.com -d www.example.com
# Wildcard via DNS-01 with a DNS plugin and a zone-scoped token
sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d example.com -d "*.example.com"
# ECDSA key (the default for new certbot certificates)
sudo certbot certonly --nginx --key-type ecdsa -d example.com

10За пределами публичного веба: mTLS, внутренняя PKI и ECH

TLS может аутентифицировать обе стороны. В mutual TLS (mTLS) клиент тоже предъявляет сертификат, который сервер проверяет по доверенному CA. Это обычная практика между сервисами, для партнёрских API и для соединений CDN — origin. Service mesh автоматически выпускают и ротируют такие сертификаты. Для внутренних сервисов можно поднять приватный CA (например, step-ca или облачный private CA), но тогда каждый клиент должен доверять этому корню, а ротация и отзыв — на вас; для публичных имён проще публичный CA через ACME. Encrypted Client Hello (ECH) скрывает hostname из SNI от наблюдателей в сети, шифруя ClientHello ключом, опубликованным в DNS-записи HTTPS. Крупные браузеры и CDN его поддерживают, так что для проксируемых сайтов он часто работает без каких-либо изменений на вашем сервере.

nginx
# nginx: require a client certificate from your internal CA
ssl_client_certificate /etc/ssl/internal/ca.pem;
ssl_verify_client on;
ssl_verify_depth 2;
# Test with a client certificate
# curl --cert client.pem --key client.key https://api.internal.example.com/health

Реальные ситуации

01

Сертификаты истекли за выходные

Проблема

В понедельник сайт показывает NET::ERR_CERT_DATE_INVALID. certbot установили несколько месяцев назад, и раньше продление работало.

Как решить

Запустите sudo certbot renew --dry-run и прочитайте ошибку. Частые причины: при изменении файрвола закрыли порт 80, редирект с HTTP на HTTPS или правило авторизации блокирует /.well-known/acme-challenge/, DNS теперь указывает на CDN или новый сервер, либо таймер отключён. Проверьте systemctl list-timers и journalctl -u certbot. Устраните причину, запустите certbot renew, перезагрузите nginx и проверьте новые даты через openssl x509 -noout -dates. Затем добавьте внешний мониторинг срока действия с алертом за 14 дней и deploy hook, который перезагружает nginx после каждого продления.

02

Приватный ключ закоммитили в репозиторий

Проблема

Разработчик по ошибке запушил privkey.pem в общий Git-репозиторий. Репозиторий приватный, но доступ есть у нескольких подрядчиков.

Как решить

Считайте ключ скомпрометированным. Немедленно выпустите сертификат с новым ключом, например sudo certbot renew --cert-name example.com --force-renewal --new-key, и перезагрузите nginx. Отзовите старый сертификат через certbot revoke --cert-path с путём к нему, указав причину keyCompromise. Удалите файл из истории репозитория инструментом для переписывания истории и ротируйте все остальные секреты из того же коммита. Добавьте каталог сертификатов в .gitignore и хук для поиска секретов, чтобы это не повторилось.

03

Android-приложение не может подключиться, а браузеры могут

Проблема

После переезда на новый сервер сайт работает во всех браузерах, но мобильное приложение и Java-клиент партнёра падают с ошибками certificate path.

Как решить

Скорее всего, в новом конфиге nginx ssl_certificate указывает на cert.pem вместо fullchain.pem, и промежуточного сертификата нет. Браузеры исправляют это закэшированными промежуточными сертификатами или через AIA fetching; многие приложения и Java-клиенты — нет. Запустите openssl s_client -showcerts и убедитесь, что видны два сертификата. Переключитесь на fullchain.pem, проверьте nginx -t, сделайте reload и прогоните SSL-чекер. Если приложение использует certificate pinning, проверьте, не закреплён ли изменившийся ключ, и планируйте обновление пинов с резервными пинами до ротации.

Шпаргалка

Согласованный протокол и шифр
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null
Срок действия и имена
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates -ext subjectAltName
Показать всю отправляемую цепочку
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
Изучить локальный сертификат
openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -text | less
Список сертификатов certbot
sudo certbot certificates
Проверить продление
sudo certbot renew --dry-run
Добавить имя в существующий сертификат
sudo certbot --nginx --expand -d example.com -d www.example.com -d shop.example.com
Заголовок HSTS (после тестирования)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Проверить, что ключ соответствует сертификату
openssl x509 -noout -pubkey -in cert.pem | sha256sum; openssl pkey -pubout -in privkey.pem | sha256sum
Поиск в логах Certificate Transparency
https://crt.sh/?q=example.com

В моих реальных проектах

  • На серверах, которыми я управляю, я использую сертификаты Let's Encrypt от certbot; HTTPS везде и автопродление — часть моего базового набора.
  • Мой базовый набор правил файрвола держит открытыми порты 80 и 443, поэтому проверки HTTP-01 и редиректы с HTTP на HTTPS работают.
  • Сервер POS SaaS использует TLS-override для Docker Compose с nginx в роли reverse proxy перед сервисами.

Вопросы и ответы

Q1Как работает рукопожатие TLS 1.3?

Клиент отправляет ClientHello с поддерживаемыми шифрами, hostname в SNI, протоколами ALPN и key share для эфемерного обмена Диффи — Хеллмана. Сервер отвечает ServerHello и своим key share, и обе стороны выводят одинаковые сессионные ключи. С этого момента всё зашифровано: сервер отправляет цепочку сертификатов, подпись, доказывающую владение закрытым ключом, и Finished. Клиент проверяет цепочку и hostname, отправляет Finished и сразу может отправить HTTP-запрос. Это один круговой путь против двух в TLS 1.2. Эфемерные ключи дают forward secrecy, поэтому последующая утечка ключа не позволит расшифровать записанный трафик.

Q2Что такое цепочка доверия?

Браузеры и операционные системы доверяют небольшому набору корневых сертификатов CA. Корневые CA подписывают промежуточные, а промежуточные — сертификаты сайтов. Когда сервер предъявляет свой leaf-сертификат вместе с промежуточными, клиент проверяет каждую подпись вверх по цепочке, пока не дойдёт до доверенного корня, а также проверяет сроки действия, hostname в Subject Alternative Name и назначение ключа. Если промежуточного сертификата нет, одни клиенты могут его скачать, а другие падают, — вот почему curl или мобильные приложения ломаются, когда десктопные браузеры работают. Корневые CA хранятся офлайн под защитой; промежуточные можно ротировать, не меняя того, чему доверяют устройства.

Q3Как гарантировать, что сертификаты в продакшене никогда не истекут?

Автоматизация плюс мониторинг. Я использую certbot или другой ACME-клиент с systemd-таймером или cron, deploy hook для перезагрузки nginx и запускаю certbot renew --dry-run после настройки и после любого изменения сервера. Порт 80 остаётся открытым для HTTP-01, либо я использую DNS-01 с API-токеном ограниченных прав. Затем мониторю снаружи: uptime-сервис присылает алерт, когда до истечения сертификата остаётся меньше примерно двух недель. Сроки действия по всей отрасли сокращаются и к 2029 году дойдут до 47 дней, поэтому всё ручное рано или поздно сломается. За CDN edge-сертификат управляется провайдером, но origin требует такой же заботы.

Q4Что такое HSTS и какие у него риски?

HSTS — это заголовок ответа Strict-Transport-Security, который велит браузеру использовать для этого домена только HTTPS в течение заданного срока, например года. После первого визита браузер сам переводит ссылки http:// на HTTPS и не позволяет пользователям пропустить ошибки сертификата, что блокирует атаки SSL stripping. С preload-списком браузеры применяют это даже при самом первом визите. Риск — в «запирании»: если какой-то поддомен, покрытый includeSubDomains, не поддерживает HTTPS или сертификат сломался, пользователи не смогут туда попасть. Поэтому я начинаю с короткого max-age, проверяю все поддомены, затем увеличиваю его, а в preload отправляю только при полной уверенности.

Q5Сайт работает в Chrome, но curl пишет «unable to get local issuer certificate». Почему?

Скорее всего, сервер отдаёт только свой leaf-сертификат без промежуточного. Десктопные браузеры часто это скрывают, потому что кэшируют промежуточные сертификаты или скачивают их через расширение AIA, а curl, многие мобильные клиенты, Node и Java так не делают. Решение — настроить полную цепочку: в nginx ssl_certificate должен указывать на fullchain.pem от certbot, а не на cert.pem. Я проверяю через openssl s_client -showcerts, что промежуточный сертификат присутствует, или использую онлайн-проверку SSL. Реже на клиентской машине устарел сам набор CA, и его нужно обновить.

Вопросы уровня senior

S1Где должен завершаться TLS в системе с CDN, балансировщиком и контейнерами?

Каждый участок должен быть зашифрован, если он проходит через сеть, которую вы не контролируете полностью. CDN завершает TLS посетителя. Между CDN и origin я использую Full (strict) с валидным сертификатом, в идеале плюс authenticated origin pulls. Балансировщик может завершать TLS и шифровать заново или пропускать TLS до nginx; завершение на нём упрощает управление сертификатами, повторное шифрование сохраняет защиту данных внутри сети. Между nginx и контейнерами на том же хосте в приватной Docker-сети обычный HTTP — распространённый и допустимый компромисс. Между хостами или в общих кластерах используйте TLS или mTLS, часто через service mesh. Меньше точек завершения — меньше ключей, которые надо защищать, но каждый участок, который инспектирует трафик, требует собственного сертификата и ротации.

S2Как подготовиться к 47-дневным сертификатам на множестве серверов?

Исходите из того, что ничего ручного не выживет. Проведите инвентаризацию всех сертификатов: веб-серверы, балансировщики, почта, VPN, аппаратные устройства и всё, что использует файл сертификата, скопированный вручную. Переведите каждый на автоматизацию через ACME или на managed-сервис вроде CDN или облачного балансировщика, который продлевает сам. Используйте клиенты с поддержкой ARI, чтобы CA мог сигнализировать о раннем продлении. Сделайте перезагрузки автоматическими через deploy hook и убедитесь, что система управления конфигурацией не перезаписывает продлённые файлы. Мониторьте снаружи срок действия и ошибки цепочки, с алертами задолго до того, как останется треть срока. Устройства, которые не умеют ACME, должны стоять за прокси, который умеет. Вложения окупаются не только ради compliance: ротации становятся рутиной, и экстренный отзыв больше не вызывает стресса.

S3Стоит ли использовать certificate pinning в мобильных приложениях?

Pinning заставляет приложение принимать только конкретные ключи, что блокирует перехват, даже если пользователь установил поддельный CA или CA скомпрометирован. Цена — хрупкость: если вы ротируете ключи без ведома приложения, перестают работать все установленные версии, а при коротких сроках сертификатов ротация частая. Если pinning обязателен, закрепляйте публичный ключ промежуточного сертификата или собственный долгоживущий ключ, а не leaf, всегда добавляйте резервные пины, предусмотрите удалённый способ обновить или отключить pinning и сохраняйте тот же ключ между продлениями, если процесс вашего CA это позволяет. Для большинства приложений достаточно стандартной валидации TLS плюс проверок Certificate Transparency на уровне платформы. Pinning обычно окупается в банковских и высокорисковых приложениях.

Глоссарий

CA
Certificate Authority: организация, которой доверяют подписывать сертификаты после проверки, что заявитель контролирует домен.
Leaf certificate
Сертификат для вашего собственного hostname, в самом низу цепочки.
Intermediate CA
Сертификат CA между корнем и вашим leaf; сервер должен отправлять его вместе с leaf.
SAN
Subject Alternative Name: список hostname, для которых действителен сертификат.
SNI
Server Name Indication: hostname, который клиент отправляет в handshake, чтобы сервер выбрал нужный сертификат.
Forward secrecy
Использование временных сессионных ключей, чтобы украденный ключ сервера не мог расшифровать ранее записанный трафик.
ACME
Протокол, по которому CA вроде Let's Encrypt автоматически выпускают и продлевают сертификаты.
HSTS
Заголовок, который велит браузерам в течение заданного срока использовать для домена только HTTPS.
Certificate Transparency
Публичные логи всех выпущенных сертификатов, чтобы владельцы доменов замечали неожиданные.
mTLS
Mutual TLS: и клиент, и сервер предъявляют сертификаты и проверяют друг друга.

Есть идея продукта?Давайте создадим его.

Расскажите о своей идее, продукте или команде. Обычно отвечаю в течение одного рабочего дня.