Что такое SSL Pinning и зачем он нужен?

SSL Pinning — это техника безопасности, используемая в мобильных и веб-приложениях для усиления защиты от атак типа "Man-in-the-Middle" (MitM). Она позволяет убедиться, что клиент (например, мобильное приложение) устанавливает соединение только с доверенным сервером, даже если злоумышленник попытается подделать сертификат через поддельный прокси или скомпрометированный сертификат.
Как работает HTTPS без SSL Pinning
Когда клиент устанавливает HTTPS-соединение, происходит стандартная проверка SSL-сертификата сервера. Эта проверка включает:
- Проверку, что сертификат выдан доверенным центром сертификации (CA);
- Сравнение доменного имени в сертификате с фактическим адресом;
- Проверку срока действия сертификата.
Однако система доверия к CA может быть уязвимой. Если злоумышленник сможет добавить собственный CA в систему (например, на скомпрометированном устройстве), он может выдать поддельный, но «доверенный» сертификат и перехватывать трафик.
Что делает SSL Pinning
SSL Pinning добавляет дополнительный уровень проверки: клиент «прикрепляет» (pin) конкретный сертификат или публичный ключ сервера, с которым он должен работать. При попытке подключения к серверу клиент сравнивает полученный сертификат с ранее сохранённым (ожидаемым). Если они не совпадают — соединение отклоняется, даже если сертификат в целом валиден по стандартным правилам HTTPS.
Варианты реализации
Существует два основных подхода к SSL Pinning:
1. Pinning сертификата
Приложение сохраняет сам SSL-сертификат сервера. При подключении сравнивает полученный сертификат с сохранённым.
- Плюсы: Просто реализовать.
- Минусы: Требует обновления приложения при обновлении сертификата.
2. Pinning публичного ключа
Сохраняется не весь сертификат, а его публичный ключ.
- Плюсы: Публичный ключ может не меняться даже при обновлении сертификата (например, при переиздании от того же CA).
- Минусы: Реализация сложнее, требует вычисления хэшей ключей.
Примеры
На Android (Java / Kotlin)
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build();
OkHttpClient client = new OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build();
На iOS (Swift)
// URLSessionDelegate метод
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge,
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// Получить серверный сертификат и сравнить с локально сохранённым
}
Преимущества
- Защита от поддельных сертификатов и MitM-атак;
- Повышение доверия к соединениям в средах с потенциально скомпрометированными устройствами.
Недостатки
- Неудобство при обновлении сертификатов: любое изменение требует выпуска новой версии приложения (если пинning реализован жёстко);
- Возможные проблемы с производительностью и сложностью поддержки;
- При ошибочной реализации можно заблокировать доступ к собственному серверу.
Лучшие практики
- Используйте pinning публичного ключа, а не всего сертификата;
- Храните несколько «пинов» (основной + резервные), чтобы облегчить обновление сертификатов;
- Устанавливайте разумные сроки жизни сертификатов;
- Реализуйте механизмы отката/обновления на клиенте (если возможно).
SSL Pinning — мощный инструмент защиты сетевого взаимодействия между клиентом и сервером, особенно в мобильных приложениях и приложениях с высокими требованиями к безопасности. Однако его внедрение требует аккуратного планирования и понимания потенциальных рисков, особенно связанных с управлением жизненным циклом сертификатов.
Эта мера не заменяет HTTPS, но делает его гораздо более устойчивым к целому классу атак.
-
-
Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.