Pull to refresh

Безопасная аутентификация между клиентом и сервером без ввода логина и пароля

Reading time7 min
Views25K
Недавно, при разработке распределенного анализатор трафика, у меня появилась задача спроектировать систему аутентификации между клиентом и сервером. Причем необходимо было спроектировать систему для двух разных ситуаций:

  • когда клиент и сервер общаются в доверенной (локальной) сети;
  • клиент и сервер взаимодействуют через глобальную, незащищенную сеть.

Отличия заключаются в том, что при взаимодействии клиента и сервера через локальную сеть, при проектировании системы исключались угрозы вторжения из вне (угроза сидящего рядом с вами хакера, перенаправляющего ваш трафик на свой компьютер, сводилась к минимуму). К тому же взаимодействие клиента и сервера в локальной сети означает, что доступ клиента и сервера к интернету отсутствует или не желателен, то есть также отсутствует доступ к центрам сертификации, и, как следствие, невозможно в полной мере использовать аутентификацию при помощи открытых ключей.

В отличие от локальное сети, где для проведения атаки злоумышленнику каким-либо образом необходимо подсоединиться к ней (а если такой сетью управляют хорошие сисадмины, то это достаточно проблематично сделать), при взаимодействии клиента и сервера через незащищенную сеть нельзя быть уверенным, что никто не прослушивает трафик. Поэтому здесь требуется алгоритм аутентификации, отличающийся от алгоритма для взаимодействия в локальной сети.


К тому же на систему аутентификации накладывались некоторые дополнительные ограничения.
В общем ограничения можно описать следующим образом:
  • требуется надежное шифрование трафика между клиентом и сервером;
  • клиент должен работать сразу после установки на компьютер, без запроса пароля у пользователя. То есть сотрудник вообще не должен знать о существовании такого клиента, установленного на его компьютере. Все настройки для клиента поступают с сервера, а клиент, в свою очередь, должен просто уметь подтвердить свою личность, чтобы отправлять зашифрованный трафик;
  • если любопытные сотрудники получат доступ к какому-либо клиенту и его секретному ключу, то максимум, что они могут сделать, это расшифровать сообщения только на определенном промежутке времени, для которого и был создан этот ключ. То есть частично обеспечивается forward secrecy (секретность будущих сообщений) и backward secrecy (секретность прошлых сообщений);
  • если сотрудники начнут без надобности устанавливать клиенты на локальные компьютеры, то это не будет критично, т.к. клиент не имеет возможностей нарушить работу сервера, или получить доступ к зашифрованным данным. К тому же сервер может забанить такие клиенты.

Исходя из этих ограничений, были выбраны следующие протоколы и алгоритмы:

  • для аутентификации в локальной сети используется протокол аутентификации, основанный на общем секретном ключе с использованием HMAC, а для генерации общего секретного ключа — алгоритм Диффи-Хеллмана (о самом алгоритме я здесь писать не буду, т.к. на хабре уже существует множество подробных статей о нем).
  • для аутентификации между клиентом и сервером в незащищенной сети, предполагается использование протокола аутентификации с помощью шифрования с открытым ключом, с использованием алгоритма RSA (про RSA можно посмотреть на википедии).

Аутентификация на основе общего секретного ключа с использованием HMAC


Данный вид аутентификации подразумевает наличие у клиента и сервера некоего секретного ключа, который известен только им двоим. Мы такой ключ сгенерировали с помощью алгоритма Диффи-Хеллмана.

HMAC (сокращение от англ. hash-based message authentication code, хеш-код идентификации сообщений). То есть это механизм, который использует криптографические хеш-функции в сочетании с секретным ключом.

Последовательность аутентификации протокола выглядит следующим образом:



Nк, Nс — 128 битное число, выбранное случайным образом клиентом и сервером по отдельности;
К, С — идентификаторы клиента и сервера (например, IP адрес);
HMAC — хэш код идентификации сообщения;
Ks — общий секретный ключ.

На первом шаге клиент посылает случайно выбранное число серверу, чтобы он мог зашифровать его общим для них ключом, и тем самым подтвердить, что он на самом деле является сервером, а не злоумышленником, который притворяется им (хотя как мы увидим далее, в нашем примере это число не шифруется, а преобразуется вместе с другими данными в хэш, что не меняет сути процесса).

На втором шаге сервер отправляет клиенту случайное число Nс, а также хэш HMAC, образованный путем хэширования значений Nк, Nс, К, С и Кs при помощи HMAC-функции. Т.к. клиент знает Nк, Nс, К, С и Кs, то он может сформировать свой хэш HMAC, и сравнить его с пришедшим от сервера. Если хэши будут совпадать, то сервер является тем, за кого себя выдает. В тоже время злоумышленник не мог бы сформировать хэш HMAC( Nк, Nс, К, С, Кs), т.к. он как минимум не должен знать секретного ключа Ks.

На третьем шаге пришла очередь клиента подтвердить свою «личность». Процесс осуществляется по аналогии со вторым шагом.

Аутентификация с помощью шифрования открытого ключа


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



Nк, Nс — 128 битное число, выбранное случайным образом клиентом и сервером по отдельности;
К, С — идентификаторы клиента и сервера (например, IP адрес);
Ks — общий секретный ключ;
Ec, Eк — открытые ключи сервера и клиента соответственно, которые передаются в виде сертификатов.

Сначала клиент запрашивает открытый ключ сервера (Ес) у центра сертификации. Затем он шифрует с помощью него случайно выбранное число и свой идентификатор (шаг 3). Только настоящий сервер может расшифровать это сообщение. Поэтому сервер, получая данное сообщение, расшифровывает его, и шифрует с помощью открытого ключа клиента (который он получает у центра сертификации) случайное число клиента, свое случайное число, и общий секретный ключ (шаг 6). Далее, если клиент является тем, за кого себя выдает, расшифровывает сообщение сервера, узнает общий секретный ключ, и для подтверждения, что он смог расшифровать сообщение сервера, отсылает серверу случайно число Nc, зашифровав его общим секретным ключом (шаг 7).

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



Дополнительная защита обеспечивается сменой общего секретного ключа (Ks) через случайный промежуток времени (Tk). Подробнее об этом написано в разделе «Анализ системы на защищенность от атак»

Алгоритм системы аутентификации


Далее все этапы установления соединения были описаны с помощью блок-схем.

Алгоритм системы аутентификации со стороны клиента выглядит следующим образом:



Со стороны сервера:



После успешной аутентификации можно передавать зашифрованный трафик. Предполагается, что трафик будит шифроваться с помощью алгоритма AES, используя секретный ключ Ks. Почему AES? Потому что это наилучший на сегодняшний день симметричный алгоритм шифрования. Подробнее о нем можно узнать в интернете.

Анализ системы на защищенность от атак


Далее я смоделировал различные ситуации, которые могут произойти, и проанализировал устойчивость системы к ним.

Уязвимость алгоритма Диффи-Хеллмана к MITM атакам

Это, пожалуй, главный недостаток данного алгоритма. Если допустить, что злоумышленник выдает себя за сервер клиенту, и за клиент серверу (например, используя ARP-spoofing), то весь трафик будит проходить через злоумышленника.



Защититься от такого рода атак можно только грамотно продумав сетевую архитектуру и правила ИБ предприятия. Например, можно установить ПО по обнаружению ARP-spoofinga и подобных атак.

Подключение клиентов к серверу без необходимости

Что может произойти, если кто-то получит клиент нашего анализатора?
С одной стороны, т.к. сервер не передает никакую важную информацию клиенту (только команды), а клиент в свою очередь никак не может получить доступ к важным данным сервера и только отсылает трафик, это не вызовет никаких серьезных неудобств.



Единственное, что может причинить неудобства, БД сервера может неприлично увеличиться, но это забота сервера и администратора отключать ненужные клиенты от работы сети (т.к. для заполнения БД требуется достаточно много времени).

С другой стороны, клиент может устроить DOS атаку, отсылая множество запросов на установление общего ключа, затем удаляя полученный ключ и отсылая новый запрос на получение секретного ключа.



Здесь можно просто напросто банить на время таких клиентов. Также клиент не может инициализировать обновление секретного ключа. Единственный, кто знает время действия общего секретного ключа — это сам сервер. И только он может посылать запрос на обновление общего секретного ключа.

Получение злоумышленником секретного ключа клиента и трафика этого клиента

В данной ситуации предполагается, что злоумышленник заполучил секретный ключ и трафик клиента.



m — сетевой пакет (сообщение), который шифруется секретным ключом.

Как говорилось ранее, установление общего секретного ключа между агентом и сервером в доверенной зоне происходит с помощью алгоритма Диффи-Хеллмана. В отличие от стандартного Диффи-Хеллмана, в моем случае предполагается смена общего ключа (Ks) через случайный промежуток времени, который лежит на интервале времени (Tmin, Tmax), где Tmin и Tmax устанавливаются в настройках серверной части приложения.

Данный способ позволяет частично обеспечить forward secrecy (секретность будущих сообщений) и backward secrecy (секретность прошлых сообщений). То есть если допустить, что находящийся внутри предприятия злоумышленник имеет записанный ранее трафик, и при этом ему удалось получить текущий общий секретный ключ Ks(i), он сможет расшифровать только такой трафик, который был передан на интервале (Tmin(i), Tmax(i)), где i — текущий номер сгенерированного общего секретного ключа.

Заключение


В данной статье было описано проектирование системы аутентификации на основе широко известных протоколов аутентификации. Было приведено краткое описание протокола аутентификации на основе общего секретного ключа с использованием HMAC, и протокола аутентификации с помощью шифрования с открытым ключом.
В конце был проведен краткий анализ подверженности спроектированной системы к компьютерным атакам.

P.S. Буду рад комментариям, исправлениям и аргументированной критике.
Tags:
Hubs:
Total votes 40: ↑36 and ↓4+32
Comments19

Articles