SSL Pinning: суть, механизм и защита от MITM-атак

Автор: IT Sectr Опубликовано: 2026-03-09 Время чтения: 9 мин

SSL Pinning — техника безопасности, при которой приложение проверяет сертификат сервера по заранее известному отпечатку или сертификату, а не полагается на цепочку доверия CA. В отличие от стандартной проверки, pinning предотвращает перехват трафика через подменные корневые центры сертификации. По данным OWASP Mobile Security Testing Guide (2025), эта техника входит в топ-3 recommended controls для защиты от MITM-атак. Без pinning атакующий с подменным корневым сертификатом может расшифровать весь HTTPS-трафик приложения.

Главное

  • SSL Pinning — привязка приложения к конкретному сертификату или отпечатку сервера вместо доверия всей цепочке CA
  • MITM-атаки предотвращаются за счёт проверки сертификата по белому списку, а не через публичные CA
  • Два основных типа — привязка сертификата (certificate pinning) и привязка открытого ключа (public key pinning)
  • Реализация на iOS требует делегата URLSession, на Android использует CertificatePinner OkHttp или Network Security Config
  • Ротация ключей — главная сложность: при смене сертификата нужно обновлять приложение через механизм backup pins

Что такое SSL Pinning?

SSL Pinning — это механизм безопасности, при котором мобильное или веб-приложение запоминает доверенный сертификат или открытый ключ сервера и отклоняет любые соединения, сертификат которых не совпадает с сохранённым. В стандартной схеме HTTPS клиент проверяет сертификат через цепочку доверия до корневого CA — любой CA может подписать сертификат для любого домена. SSL Pinning устраняет это слабое место: вместо доверия сотням CA приложение доверяет только одному конкретному сертификату.

Проблема стандартной проверки в том, что любой из сотен корневых CA может выпустить валидный сертификат для вашего домена — случайно или по принуждению. Атакующий, получивший доступ к корпоративному прокси с собственным корневым сертификатом, может проводить MITM-атаку без предупреждения браузера. SSL Pinning закрывает эту уязвимость: даже если CA выпустил подменный сертификат, приложение его отклонит, так как отпечаток не совпадает с зафиксированным.

В мобильных приложениях SSL Pinning особенно важен, потому что устройства часто работают в незащищённых сетях — общественный Wi-Fi, корпоративные прокси с инспекцией трафика, заражённые точки доступа. По данным Verizon Mobile Security Index (2025), более 60% утечек данных в мобильных приложениях связаны с перехватом трафика на транспортном уровне.

Зачем нужен SSL Pinning в мобильной разработке

Мобильные приложения передают чувствительные данные — токены аутентификации, платёжную информацию, персональные данные пользователей. Без дополнительной защиты HTTPS может быть скомпрометирован через подмену корневого сертификата на устройстве — например, после установки корпоративного профиля или вредоносного приложения. SSL Pinning гарантирует, что даже если на устройстве установлен подменный корневой CA, приложение продолжит проверять сертификат по собственному whitelist.

Как работает SSL Pinning?

Процесс SSL Pinning состоит из трёх этапов: захват отпечатка, проверка при соединении и обработка ошибки. На этапе разработки инженер получает SHA-256 отпечаток сертификата сервера (openssl x509 -fingerprint -sha256) и встраивает его в код приложения или конфигурационный файл. При каждом HTTPS-запросе приложение вычисляет отпечаток полученного сертификата и сравнивает его с сохранённым — если значения не совпадают, соединение разрывается.

Первый этап — пиннинг на этапе сборки: разработчик заранее знает сертификаты сервера и встраивает их хеши. Второй этап — пиннинг при первом соединении (trust on first use, TOFU): приложение запоминает сертификат при первом запросе и использует его для проверки всех последующих. TOFU удобен для динамических сред, но уязвим при первой атаке — если первое соединение уже перехвачено, подменный сертификат будет принят как доверенный.

Критическая деталь — резервные отпечатки (backup pins). Сертификаты имеют срок действия, и при их замене приложение без обновления потеряет соединение с сервером. Инженеры закладывают 2–3 дополнительных отпечатка — например, отпечаток резервного сертификата и отпечаток корневого CA. Если основной сертификат меняется, приложение проверяет по backup pins, и соединение продолжает работать.

bash
# Получение SHA-256 отпечатка сертификата
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
  openssl x509 -pubkey -noout | \
  openssl pkey -pubin -outform der | \
  openssl dgst -sha256 -binary | \
  base64

Типы SSL Pinning

Различают два основных подхода к реализации пиннинга: привязка к сертификату целиком (certificate pinning) и привязка к открытому ключу (public key pinning). Каждый подход имеет свои сильные стороны и ограничения, влияющие на безопасность и удобство сопровождения.

ТипОбъект фиксацииГибкостьБезопасность
Certificate PinningВесь сертификат X.509Низкая — при смене сертификата требуется обновлениеВысокая — точная привязка
Public Key PinningОткрытый ключ сертификатаСредняя — ключ может быть в новом сертификатеВысокая — менее чувствителен к деталям сертификата
Hash PinningSHA-256 хеш сертификата или ключаВысокая — можно менять сертификаты без смены ключаСредняя — зависит от стойкости хеша

Certificate Pinning

Привязка к сертификату — самый строгий метод. Приложение хранит копию доверенного сертификата или его SHA-256 отпечаток и сравнивает с сертификатом сервера при каждом HTTPS-соединении. Этот метод обеспечивает максимальную безопасность, но создаёт проблемы при ротации — сертификаты обычно действуют 1–2 года, после чего требуется принудительное обновление приложения. Рекомендуется для критичных систем с контролируемым циклом обновления.

Public Key Pinning

Фиксация открытого ключа — более гибкий подход. Вместо целого сертификата приложение запоминает только открытый ключ RSA или ECDSA сервера. Ключ может оставаться неизменным при перевыпуске сертификата, если компания использует одну и ту же ключевую пару. Это снижает частоту обновлений приложения. Однако если ключ скомпрометирован, потребуется каскадная замена на всех клиентах.

SSL Pinning на iOS

На платформе Apple SSL Pinning реализуется через делегат URLSession. Разработчик создаёт класс, реализующий протокол URLSessionDelegate, и переопределяет метод didReceive challenge, где вручную проверяет сертификат сервера против сохранённых отпечатков. Альтернативный подход — использование Alamofire с ServerTrustManager, который упрощает конфигурацию.

swift
class SSLPinningDelegate: NSObject, URLSessionDelegate {
    let pinnedHash = "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg="

    func urlSession(_ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        guard let serverTrust = challenge.protectionSpace.serverTrust
            else { return completionHandler(.cancelAuthenticationChallenge, nil) }

        if validate(serverTrust, pinnedHash) {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}

В примере делегат получает запрос на аутентификацию от URLSession, извлекает serverTrust из challenge и сравнивает SHA-256 отпечаток сертификата с сохранённым. Если отпечаток совпадает — соединение продолжается, иначе challenge отклоняется. Для продакшена стоит добавить проверку нескольких backup pins и логирование ошибок для мониторинга.

Network Security Config на iOS

Начиная с iOS 14 Apple добавила встроенную поддержку Certificate Pinning через Info.plist. Разработчик указывает доверенные сертификаты в ключе NSAppTransportSecurity с подсловарём NSPinnedDomains. Этот подход не требует написания кода, но менее гибкий — невозможно динамически менять pins или логгировать ошибки проверки.

SSL Pinning на Android

На Android существует три основных способа реализации SSL Pinning: через CertificatePinner библиотеки OkHttp, через Network Security Config в XML и через кастомную проверку в HttpsURLConnection. OkHttp — самый популярный и рекомендуемый подход, используемый в Retrofit и других HTTP-клиентах.

kotlin
val certificatePinner = CertificatePinner.Builder()
    .add("api.example.com",
        "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=")
    .add("api.example.com",
        "sha256/FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=")  // backup pin
    .build()

val client = OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build()

В конфигурации OkHttp разработчик указывает домен и один или несколько SHA-256 отпечатков. При первом отпечатке OkHttp сравнивает сертификат сервера с указанными pins. Если совпадения нет, клиент выбрасывает SSLPeerUnverifiedException. Backup pin обязателен — без него при смене сертификата API-запросы сразу начнут падать.

Network Security Configuration на Android

Android поддерживает декларативный Certificate Pinning через XML-конфигурацию начиная с API 24. Файл res/xml/network_security_config.xml содержит список доменов и их отпечатков. Этот метод удобен для статических конфигураций, но не позволяет реализовать TOFU или кастомную логику проверки с логированием аномалий.

xml
<!-- res/xml/network_security_config.xml -->
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">api.example.com</domain>
        <pin-set expiration="2027-12-31">
            <pin digest="SHA-256">
                Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=</pin>
            <pin digest="SHA-256">
                FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=</pin>
        </pin-set>
    </domain-config>
</network-security-config>

Плюсы и минусы SSL Pinning

SSL Pinning значительно повышает безопасность мобильного приложения, но вводит операционные сложности. Главный плюс — защита от MITM-атак даже при компрометации корневых CA. Приложение доверяет только тем сертификатам, которые явно указаны разработчиком, а не всей инфраструктуре публичных центров сертификации. Это особенно критично для финансовых приложений, мессенджеров и-приложений с чувствительными данными.

Основной минус — сложность ротации сертификатов. Если сертификат истекает или отзывается, пользователи без обновления приложения теряют соединение. Решается через backup pins и механизм постепенного обновления: новое приложение знает старый и новый сертификаты, а после полного обновления пользователей старый pin удаляется из кода. Рекомендуется закладывать минимум 2 backup pins — один для текущего сертификата, один для будущего.

Ещё один компромисс — невозможность использовать публичные прокси для отладки трафика (Charles Proxy, Burp Suite) без отключения пиннинга. Это усложняет отладку сетевых запросов на этапе разработки. Решение — условная компиляция: в debug-сборке пиннинг отключён, в release — включён. OWASP рекомендует использовать флаг BuildConfig.DEBUG для переключения.

АспектПреимуществоНедостаток
БезопасностьЗащита от MITM через подменные CAСложность при компрометации ключа
СопровождениеЯвный контроль доверияРотация требует обновления приложения
ОтладкаГарантия соединения с правильным серверомБлокировка отладочных прокси

Часто задаваемые вопросы

В чём разница между SSL Pinning и стандартной проверкой HTTPS?

Стандартная проверка HTTPS доверяет любому сертификату, подписанному известным корневым CA. SSL Pinning доверяет только конкретному сертификату или ключу — если CA выпустит подменный сертификат, приложение его отклонит.

Как часто нужно обновлять pinned сертификаты?

Сертификаты обычно действуют 1–2 года. Рекомендуется обновлять pins за 3–6 месяцев до истечения текущего сертификата, добавляя новый отпечаток как backup pin, а после ротации удалять старый.

Можно ли использовать SSL Pinning с CDN?

Да, но нужно учитывать, что CDN может менять сертификаты при переключении между edge-серверами. Рекомендуется привязываться к открытому ключу, а не к конкретному сертификату, и использовать несколько backup pins.

Что произойдёт при ошибке проверки SSL Pinning?

Соединение разрывается с ошибкой — на Android это SSLPeerUnverifiedException, на iOS challenge отклоняется с .cancelAuthenticationChallenge. Приложение должно корректно обработать эту ошибку и уведомить пользователя.

Обязателен ли SSL Pinning для всех мобильных приложений?

Нет, но OWASP рекомендует его для приложений, работающих с чувствительными данными: банкинг, медицина, корпоративные системы. Для простых read-only приложений стандартной HTTPS-проверки с сертификатами EV обычно достаточно.

Итоги

  • SSL Pinning — привязка приложения к конкретному сертификату или ключу сервера, устраняющая зависимость от цепочки доверия CA
  • Два основных типа — certificate pinning (строгий, привязан к сертификату) и public key pinning (гибкий, привязан к ключу)
  • Backup pins — обязательный элемент: минимум 2 резервных отпечатка для плавной ротации сертификатов
  • iOS — реализация через URLSessionDelegate с ручной проверкой serverTrust или Alamofire ServerTrustManager
  • Android — OkHttp CertificatePinner (программно) или Network Security Config (декларативно через XML)
  • Риск — при неправильной ротации pinned сертификатов пользователи теряют соединение до обновления приложения
  • Рекомендация — использовать SSL Pinning для приложений с финансовыми, медицинскими или корпоративными данными

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также