Протокол безопасности для генерации общего секретного ключа на стороне сервера

Я пытаюсь реализовать систему безопасности, которая имеет следующие требования:

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

Позвольте мне попытаться дать графическое представление этого:

            Client                         Server
.--------------^-----------.       .----------^----------.

          f(client-id 1)              g(client-id 1)
PASSWORD ----------------> request 1 ----------------> KEY
   || equal                                             || equal
PASSWORD ----------------> request 2 ----------------> KEY
          f(client-id 2)              g(client-id 2)

Здесь f() [g()] - это функции, которые клиент [сервер] применяет к паролю [запрос] для получения запроса [ключ]. Эти функции могут зависеть от идентификатора клиента.

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

  1. "Легко понять": клиенты хэшируют пароль. Каждый клиент и сервер используют стандартный механизм (например, SSL) для защиты своего соединения и отправки хэша по этому соединению.

  2. "Немного умнее": на сервере закодирован фиксированный закрытый ключ, а каждому клиенту закодирован открытый ключ. Клиенты хешируют пароль, XOR его со своим идентификатором клиента, шифруют результат с помощью RSA/PGP с использованием открытого ключа. Затем сервер расшифровывает запрос, используя закрытый ключ, и XOR-результат с идентификатором клиента для получения хэша пароля.

В обоих случаях сервер получает один и тот же секрет для клиентов: хэш пароля. Преимущество второй версии состоит в том, что нет необходимости в дополнительных издержках полноценной системы обмена ключами и шифрования, поскольку, к сожалению, я не смогу полагаться на SSL во всех случаях. Фактически, это позволяет мне генерировать секрет сервера в одном запросе без какого-либо рукопожатия. Client-id-XOR во второй версии используются для предотвращения повторных атак, когда в противном случае третье лицо с другим идентификатором клиента может просто отправить одно и то же зашифрованное сообщение на сервер, чтобы сгенерировать тот же секрет. По сути, это простой способ добавить соль.

Теперь вопрос:

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

1 ответ

Решение

Наверное, не берутся... Вопрос, вероятно, слишком расплывчатый...

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

Другие вопросы по тегам