Безопасный метод проверки подлинности API

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

Первое предложение:

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

Шаг второй) Клиент теперь сохраняет первичный токен и создает новый хеш-маркер с использованием первичного токена + переменной current_time, отправленной в запросе аутентификации (позволяет вызывать этот новый токен, main_token), и сервер делает то же самое и создает тот же токен, используя тот же алгоритм.

Шаг третий) Каждый раз, когда клиент запрашивает API-интерфейс сервера, он отправляет main_token на сервер, теперь сервер сравнивает созданный в нем токен, а main_token отправляется клиентом, если он совпадает, это означает, что пользователь реальный

Второе предложение:

Шаг первый) Клиент генерирует две случайные клавиши ($ key1 = rand (10000,90000); $ key2 = rand (10000,90000);) При каждом запросе API клиент создает хэш с использованием типа запроса и два ключа со сложным алгоритмом и отправляет эти два ключа + хэш на сервер

Шаг второй) Сервер, используя тот же алгоритм, который используется в клиенте, создает хеш, и сравнивается с тем, который был отправлен клиентом, если он совпадает, сервер продолжает обрабатывать запрос


Теперь возникает вопрос: какой из них является наиболее логичным и безопасным способом для защиты запросов api

С наилучшими пожеланиями

Ответы

Ответ 1

Ни одно из решений не имеет никакой пользы для безопасности.

Первое предложение

Как только у меня есть main_token, я могу вычислить любой хеш (main_token + timestamp). Все, что мне нужно для доступа к API, это main_token, так зачем беспокоиться о бизнесе timestamp?

Второе предложение

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

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

Фаза аутентификации (SSL)

  • Клиент
  • отправляет пользователя/пароль и получает "Secret_token", который является случайной строкой.
  • Secret_token хранится на стороне клиента и на стороне сервера.
  • Secret_token никогда не переносится по кабелю снова.

Фаза запроса API

  • клиент создает запрос
  • клиент нормализует запрос
  • клиент вычисляет подпись * нормализованного запроса с помощью Secret_token
  • клиент отправляет запрос + подпись на сервер
  • сервер нормализует запрос
  • сервер вычисляет подпись нормализованного запроса с помощью Secret_token
  • если соответствие подписи, сервер отправляется с запросом

Вычислить подпись

Сначала нормализуйте запрос. Это может означать извлечение важных параметров, включая метод (post, get, action, timestamp) и их упорядочение. Затем запускаем эту строку через алгоритм HMAC, который принимает параметр Secret_token как параметр.

Анализ

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

Примечание: по-прежнему небезопасно отправлять поверх открытого текста, использовать SSL.

HMAC - хорошо известное решение. См:

Ответ 2

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

Учитывая, что вы используете SSL/TLS для своих подключений, нет риска того, что имя пользователя/пароль будет обнаружено. И также нет возможности повторной атаки на SSL, поэтому нет необходимости в истечении срока действия.

Я бы рекомендовал сохранить его простым и использовать существующие протоколы, которые уже были разработаны. Когда дело доходит до безопасности, вы, вероятно, не должны пытаться изобретать колесо, если у вас нет убедительных оснований для этого.

Ответ 3

Первые несколько наблюдений

  • В первом подходе маркер по существу становится длинным живым паролем. Он используется повторно с каждым запросом. Итак, если этот токен взломан, вы закончили. Не сказать, что это обескураживает, так как OAuth 2 делает именно это, но SSL здесь абсолютно необходим. Кроме того, если вы пойдете с этим, вам нужно будет убедиться, что токены имеют дату истечения срока действия и механизм, обеспечивающий быструю отмену токенов в случае компрометации.

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

Оба подхода действительны и широко используются. Итак, если вы не хотите SSL, то 2 - это путь. Если вы в порядке с SSL, OAuth - это еще один вариант. То, что я бы рекомендовал, на самом деле идет с установленными методами в любом из них. Если вы используете 1), тогда посмотрите на Oauth2, если вы идете с 2), тогда придерживайтесь схемы AWS (строго говоря, это не стандарт, но его широко документированный).

Некоторые ссылки, которые, я думаю, могут быть полезны

http://www.wolfe.id.au/2012/10/20/what-is-hmac-and-why-is-it-useful/

http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

http://blog.cloudfoundry.com/2012/10/09/securing-restful-web-services-with-oauth2/

Ответ 4

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