Что такое закрепление сертификата в Android

Фразу «закрепление сертификата» я впервые услышал 5 лет назад, когда меня неожиданно пригласили на встречу с клиентами. Там они объясняли свои требования: повысить безопасность мобильного приложения с помощью закрепления сертификата. Тогда я не знал, что это значит, но пообещал выполнить задачу. Так что же такое закрепление (pinning) сертификата?

Закрепление сертификата предполагает, что нужно жестко закодировать в приложении общедоступный сертификат сервера и разрешить подключения только с ним. После этого не получится принимать все доверенные сертификаты для соединений HTTPS  —  они будут рассматриваться как недействительные. Это сокращает возможности для атак на приложение: даже если злоумышленник сможет обмануть центр сертификации и получит сертификат для используемого URL-адреса, он все равно будет отклонен приложением, поскольку не входит в список доверенных.

Сертификаты выдаются центрами сертификации (англ. Certificate Authorities, CA)  —  это крупные компании, такие как Verisign, DigiCert и т. д. Клиент, желающий получить цифровой сертификат, заполняет форму-заявку и вносит оплату. После проверки через некоторое время сертификат генерируется и отправляется заказчику. Процесс похож на получение цифрового паспорта, в котором хранится ваша цифровая личность.

Вот так выглядит цифровая сертификация:

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

Выданный заказчику сертификат (зеленый блок)  —  это конечный сертификат (leaf), который устанавливается на стороне сервера. Этот сертификат подтверждается в цепочке сертификатом CA-SUB 2. CA-SUB 2 подписывается сертификатом CA-SUB 1 и, наконец, CA-SUB 1 подписывается ROOT CA от эмитента центра сертификации. Так выглядит цепочка сертификатов.

Ниже показана цепочка для сайта Medium на момент написания статьи: корневой (root) и промежуточный (intermediate) сертификаты, а также конечный (leaf), который содержит цифровую идентификацию домена medium.com.

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

Теперь возникает вопрос: какой сертификат закрепить?

Закрепление корневого сертификата

В процессе выдачи клиентам сертификата задействованы около 100 CA. Это означает, что если мы планируем закрепление к root, то разрешаем подключения для всех сертификатов, выданных этими CA. А таких, вероятно, очень много.

Плюсы

  • Длительный срок действия закрепленного сертификата. Не нужно контролировать его завершение.
  • Легко вносить изменения в цепочку конечных/промежуточных сертификатов.

Минусы

  • Минимальная безопасность. Приложение будет доверять любому сертификату, выданному такими CA даже потенциально ненадежным людям.

Закрепление промежуточного сертификата

Плюсы

  • Никакие изменения в конечных сертификатах не потребуют обновления приложения.
  • Длительный срок действия.

Минусы

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

Закрепление конечного сертификата

Плюсы

  • Лучшая безопасность. Закрепляя конечный сертификат, вы почти 100% гарантируете его подлинность и, таким образом, действительность цепочки.

Минусы

  • Короткий срок действия.
  • Для обновления сертификатов необходимо часто обновлять приложение.

Итак, какой из них выбрать для закрепления? Все зависит от обстоятельств. Вот несколько советов.

  • Если вы впервые закрепляете сертификат, не выбирайте конечный (leaf).
  • Не стоит закреплять этот сертификат, если нет тесного сотрудничества с бэкенд-командой. Часто может возникать недопонимание, а некоторые пользователи будут заблокированы из-за несвоевременного обновления приложения.
  • Всегда имейте запасной вариант. Встройте в приложение функцию принудительного обновления. Она пригодится в случае недостатка времени для перехода на последнюю версию.

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

Читайте нас в TelegramVK и Дзен


Перевод статьи Kliment Joncheski: Android certificate pinning — Tips and lessons learned

Предыдущая статьяСовместное использование кода в приложениях React и React Native
Следующая статьяСоздание API в R при помощи Plumber