Все, что необходимо знать о технологии HTTP Public Key Pinning (HPKP)

Все, что необходимо знать о технологии HTTP Public Key Pinning (HPKP)

В ближайшие несколько лет технология привязывания ключей (key pinning) будет главной надеждой в системе безопасности протокола TLS, делая целевые атаки, связанные с Центрами Сертификации, намного более рискованными.

Автор: Robert Love

В ближайшие несколько лет технология привязывания ключей (key pinning) будет главной надеждой в системе безопасности протокола TLS, делая целевые атаки, связанные с Центрами Сертификации, намного более рискованными. Пока мы ждем появления новых систем с встроенным привязыванием ключей, уже сейчас можно воспользоваться технологией HTTP Public Key Pinning (HPKP), позволяющей выполнять привязывание ключей «на коленке».

Цепочка сертификатов

Главный компонент в протоколе шифрования – идентификация оппонента, а вовсе не сам алгоритм. Даже самое стойкое шифрование бесполезно, если вы общаетесь не с тем, с кем намеревались. В протоколах SSL/TLS идентификация реализована на базе цепочки сертификатов, представляющих собой серию сертификатов стандарта X.509 с публичными ключами. Ваш браузер доверяет набору корневых сертификатов, принадлежащих Центрам Сертификации. Эти центры в свою очередь передают сертификаты веб-сайтам, которые вы посещаете. Когда, например, вы заходите на сайт rlove.org, ваш браузер проверяет цепочку сертификатов, начиная с того, которым владеет сайт rlove.org и далее по цепочке до корневого сертификата. Если ваш браузер доверяет корневому сертификату, вы точно знаете, что общаетесь со мной, а не со злоумышленником.

Глобальная проблема

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

Идеальная защита от MITM-атак – предварительный обмен ключами. В этой статье я расскажу о технологии, которая также поможет значительно снизить риск MITM-атаки. Суть механизма заключается в ограничении сертификатов, используемых в цепочке на стороне сайта. Кроме того, эта технология позволяет детектировать атаки прямо во время их осуществления.

Привязывание публичных ключей

Технология HTTP Public Key Pinning (HPKP) является наброском IETF-стандарта, реализующего механизм прикрепления публичных ключей через HTTP-заголовок, который заставляет браузеры затребовать сертификат из белого списка для всех последующих соединений с конкретным веб-сайтом. Этот метод серьезно сокращает вероятность осуществления успешной MITM-атаки. Вместо любого корневого сертификата, мы запрашиваем конкретный корневой и промежуточный сертификат или даже точный публичный ключ.

HTTP-заголовок

Заголовок, используемый в технологии HPKP, выглядит так:

Public-Key-Pins: pin-sha256="XXX"; pin-sha256="YYY"; max-age=ZZZ

где XXX – SHA256-хеш публичного ключа, закодированный в base64, для сертификата из белого списка; YYY – резервная копия того же самого ключа; ZZZ – время жизни (в секундах) для белого списка. Заголовок также может содержать директиву includeSubdomains, предписывающую браузерам применять белый список ко всем хостам данного домена. Директива report-uri предписывает браузерам отправлять отчеты о проверках привязки, завершившихся неудачно.

Вы можете указать столько директив pin-sha256, сколько захотите. В цепочке сертификатов должна быть только одна сигнатура (fingerprint). Кроме того, необходимо указать как минимум одну сигнатуру, которая не входит в текущую цепочку. Другими словами, стандарт предписывает иметь резервную копию привязанного ключа.

Что привязывать

Наилучший вариант – привязывать ваш собственный публичный ключ. Однако здесь потребуется уделить особое внимание управлению копиями ключей, что может вызвать затруднения, если вы часто меняете сертификаты. Более простой, но менее безопасный способ – привязать первый промежуточный сертификат из цепочки, то есть один из сертификатов вашего сайта. Это позволит упростить процесс управления вашими сертификатами и в то же время защитит от MITM-атаки.

Генерирование SPKI Fingerprint

Технология HPKP требует SHA256-хеш публичного ключа, закодированный в base64, который вы хотите привязать. Вы можете легко получить ключ либо при помощи запроса на получение сертификата (certificate signing request; CSR), либо из сертификата на базе стандарта X.509. Вам нужен только один ключ.

Генерируем содержимое для директивы pin-sha256 на базе публичного ключа (pub.key):

openssl rsa -pubout -in pub.key -outform der | \
openssl dgst -sha256 -binary | \
base64

Генерируем на базе CSR (my.csr):

openssl req -noout -in my.csr -pubkey | \
openssl rsa -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64

Генерируем на базе сертификата, закодированного в формате PEM (certificate.pem):

openssl x509 -noout -in certificate.pem -pubkey | \
openssl rsa -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64

После выполнения команд, показанных выше, получите нечто подобное:

LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=

Эту строку необходимо добавить в директиву pin-sha256. Вы можете повторить этот процесс для каждого ключа, который хотите привязать. Например, если у вас есть два сертификата для сайта, можете привязать оба. Как было сказано выше, вам нужна отдельная директива pin-sha256 с резервным ключом.

Настройка заголовка

Поскольку неправильно сконфигурированный HPKP-заголовок может сделать ваш сайт недоступным, выкатывать обновления следует с осторожностью. Несколько советов:

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

  • Используйте заголовок Public-Key-Pins-Report-Only для генерации и отправки отчетов о неудачах на адрес, содержащийся в параметре report-uri, без принудительного привязывания.

  • Пробуйте различные привязки от разных Центров Сертификации.

Настройка веб-сервера

При использовании технологии HPKP не требуется специальной поддержки HTTP-сервера; нужно лишь добавить новый заголовок. Настройка для Apache:

Header set Public-Key-Pins "pin-sha256=\"XXX\"; pin-sha256=\"YYY\"; max-age=ZZZ"

Настройка для Nginx:

add_header Public-Key-Pins 'pin-sha256="XXX"; pin-sha256="YYY"; max-age=ZZZ';

Более общую информацию о конфигурировании протоколов SSL/TLS для Apache и Nginx можно почерпнуть в других моих статьях (ссылка 1, ссылка 2).

Верификация привязанных ключей

Верификация является нетривиальной задачей, поскольку проект стандарта требует успешной проверки ключа перед запоминанием привязанной сигнатуры. Таким образом, вы не можете работать с непонятной сигнатурой для верификации неудачи при привязывании ключа. Успешное подключение к веб-серверу также не означает, что привязывание запомнилось. Простейший способ проверки - при помощи команды chrome://net-internals/#hsts. В разделе Query domain введите адрес вашего сайта и проверьте, что сигнатуры ключей отображаются в списке под строкой dynamic_spki_hashes. Браузер Chrome будет хранить сигнатуры только в случае успешной верификации.

Отчет о неудачных проверках

В спецификации заложен механизм отправки отчетов при неудачной проверке ключа. Отчеты отправляются по адресу, указанному в директиве report-uri. Эта возможность полезна не только на этапе отладки, но и при детектировании MITM-атак против ваших пользователей. На самом деле, только само присутствие этой возможности делает технологию Public Key Pinning устойчивой к MITM-атакам.

Отчеты отправляются через HTTP POST следующего JSON-сообщения:

{
  "date-time": date-time,
  "hostname": hostname,
  "port": port,
  "effective-expiration-date": expiration-date,
  "include-subdomains": include-subdomains,
  "noted-hostname": noted-hostname,
  "served-certificate-chain": [
    pem1, ... pemN
  ],
  "validated-certificate-chain": [
    pem1, ... pemN
  ],
  "known-pins": [
    known-pin1, ... known-pinN
  ]
}

Поддержка браузеров

Технология HPKP поддерживается браузерами Chrome 38, Firefox 35 (и более поздних версиях).

Недостатки HPKP

Хотя у технологии HPKP есть несколько недостатков, в целом я рекомендую ее к использованию. Самая главная уязвимость заключается в том, что HPKP – это механизм вида trust-on-first-use (доверие при первом использовании). Иными словами, пользователь не сможет узнать о MITM-атаке при первом подключении к сайту. С другой стороны, для повторной MITM-атаки злоумышленнику нужно перехватить все соединения к веб-сайту. Учитывая характер сегодняшних угроз, технология HPKP является вполне приемлемой защитой. Примечательно, что злоумышленник перед тем, как осуществить MITM-атаку, обязан знать, хранятся ли на целевой машине привязанные ключи. Иначе в браузере пользователя появится грозное предупреждение (и, возможно, отправится отчет администратору сайта) об ошибке при верификации.  

Ищем баги вместе! Но не те, что в продакшене...

Разбираем кейсы, делимся опытом, учимся на чужих ошибках

Зафиксируйте уязвимость своих знаний — подпишитесь!