Поиск ввода: поддержка сеанса сервера без состояния сервера - PullRequest
0 голосов
/ 11 февраля 2011

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

Обзор проблемы

У меня есть интерфейс, в котором клиент поддерживает жизненный цикл сеанса (это сеанс HTTP на веб-сервере, но это не имеет значения).

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

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

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

На сервере есть явный метод authenticate. Тогда возникает проблема: как сервер проверяет, что при вызове другого метода вызывающая сторона предварительно аутентифицировалась с использованием метода authenticate, не сохраняя состояния сеанса на сервере?

Предлагаемое решение

Вот схема, которую я придумала:

Метод authenticate принимает учетные данные в качестве входных параметров. После успешной аутентификации сервер возвращает две вещи:

  • Отметка времени, указывающая время, когда была выполнена аутентификация.
  • Зашифрованная версия кортежа {username, timestamp}, зашифрованная закрытым ключом

При последующих вызовах методов клиент передает оба этих значения обратно на сервер. Затем сервер расшифровывает зашифрованный кортеж {username, timestamp}. Если дешифрованная метка времени соответствует незашифрованному значению, которое также было отправлено клиентом, сервер знает, что клиент предварительно прошел аутентификацию (поскольку это единственный способ получить действительное зашифрованное значение). Расшифрованное имя пользователя сообщает серверу, какой пользователь прошел аутентификацию.

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

So

Боюсь, что эта схема наивна с дюжины способов. Какие слабости или плохую логику вы видите?

1 Ответ

0 голосов
/ 19 июля 2011

В случае, если кому-то все равно (что кажется маловероятным, учитывая внимание, которое уделяется этому вопросу!), Мы в итоге реализовали схему, аналогичную описанной выше.

Некоторые детали могут отличаться:

  • Сервер создает токен сеанса на основе имени пользователя, метки времени начала сеанса (переданной обратно пользователю) и соли.
  • Клиент не передает этот токен обратно на сервер. Вместо этого создается хеш MD5 из всего содержимого запроса, объединенного с этим токеном.
  • Хэш MD5 отправляется на сервер вместе с отметкой времени и именем пользователя (и запросом). Затем сервер заново создает маркер сеанса и выполняет тот же алгоритм хеширования. Если хеши MD5 совпадают: действительный запрос.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...