Certificate pinning

Pinning — приложение (или браузер) хранит у себя отпечаток или публичный ключ конкретного серта/CA, и принимает только его. Никакие другие валидные CA не помогут атакующему подделать соединение.

Стандартная модель TLS доверяет ~100 корневым CA. Компрометация любого из них = MITM на любой сайт. Pinning ограничивает: «даже если Comodo выпустит валидный серт на google.com — приложение его отвергнет, ему нужен именно Google-cert».

Виды pinning

Что закрепленоОсобенности
Cert pinningОтпечаток самого серта. Легко сломать при ротации.
SPKI pinningSubject Public Key Info. Можно перевыпустить cert с тем же ключом — pinning продолжит работать.
CA pinningОтпечаток промежуточного или корневого CA. Более гибко, менее строго.

Практика: pin-ят SPKI + запасной SPKI (backup), чтобы при компрометации основного ключа переключиться на резервный без обновления приложения.

HPKP (умер)

HTTP Public Key Pinning (RFC 7469) — заголовок для веба:

Public-Key-Pins: pin-sha256="base64=="; pin-sha256="backup=="; max-age=5184000

Chrome удалил поддержку в 2018, Firefox в 2020. Причины:

Pinning в мобильных приложениях

Живёт и здравствует. Банковские, платёжные, мессенджеры-приложения зашивают pin ключей своих серверов прямо в бинарник.

Android

// Network Security Config
<domain-config>
  <domain>api.mybank.com</domain>
  <pin-set>
    <pin digest="SHA-256">AAAAAAAAAAAAA=</pin>
    <pin digest="SHA-256">BBBBBBBBBBBBB=</pin>
  </pin-set>
</domain-config>

iOS

Через URLSession delegate urlSession:didReceiveChallenge: — вручную сравнить с локальным списком.

Библиотеки

Обход pinning

Стандартный кейс для security-research/pentester-ов:

Всё это требует root/jailbreak или debuggable-версии приложения. Обычному пользователю не нужно, но с точки зрения защиты — pinning не непробиваем, это удобство и «второй эшелон» защиты.

См. также