Использование системы ключей API - PullRequest
1 голос
/ 09 ноября 2011

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

Я думаю, что будет работать, если у меня будет личный ключ / секрет для каждой учетной записи.Каждый запрос содержит время, идентификатор учетной записи и хэш (время + секрет).
Затем сервер может сделать то же самое с секретом пользователя из базы данных и проверить его по хешу, отправленному клиентом.

Это разумный способ сделать это?Он открыт для атаки грубой силой, но я думаю, что пока секрет длинный (то есть, uuid), это не должно быть слишком большой проблемой ...

A Мысль

Любой может подать другой запрос с тем же временем и хэшем и принять его, в конце концов, его действительным, верно?

Ответы [ 3 ]

4 голосов
/ 09 ноября 2011

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

Server                Client

    ---->challenge --->
    <----response------

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

К сожалению, для этого требуется состояние , и вся проблема с протоколами RESTful заключается в том, что они не хотят поддерживать состояние.И все же они хотят аутентифицироваться ...

Таким образом, у вас действительно есть три варианта:

Вариант 1. Сделайте вид, что проблема не существует, и используйте протокол аутентификации без сохранения состояния.Это ничем не отличается от использования куки.Nonce + password-hash не более безопасен, чем cookie.Файлы cookie могут быть украдены и т. Д., И воспроизведено .Вся сеть теперь страдает от этих атак воспроизведения.

Вариант 2: Попробуйте внедрить протокол аутентификации в метод связи без сохранения состояния.Здесь вы бы попросили клиента отправить вам метку времени UTC вместо одноразового номера.Использование метки времени обеспечивает ограниченную защиту от воспроизведения.Очевидно, что ваши часы не будут синхронизированы с часами клиента, поэтому ваш сервер разрешит любую временную метку в пределах некоторого запаса ошибок, и этот запас ошибок будет запасом воспроизведения протокола аутентификации.Обратите внимание, что это нарушает REST, потому что сообщение аутентификации не идемпотентно.Идемпотент подразумевает, что «может быть успешно воспроизведен злоумышленником».

Вариант 3: Не пытайтесь подключить протокол аутентификации к протоколу без сохранения состояния.Используйте SSL.Используйте клиентские сертификаты.Вместо того, чтобы клиент загружал строку, позвольте ему сгенерировать сертификат или вы можете предоставить ему пару ключей.Они аутентифицируются через SSL и не аутентифицируются на вашем уровне REST.У SSL много «накладных расходов».Он не легкий, именно потому, что решает эти проблемы воспроизведения.

Таким образом, в конечном итоге это зависит от того, насколько вы цените доступ к своим API.

2 голосов
/ 09 ноября 2011

Для API, которые только получают данные (кроме личных данных), а не создают, изменяют или удаляют данные, вариант 1 в этот ответ может быть адекватным. См., Например, API REST Bing Maps и Google. Веб-службы Maps Premier (здесь Google Maps также хеширует URL-адрес с цифровой подписью и специальный ключ, известный только пользователю API, который при обеспечении защиты от изменения URL, по-видимому, до сих пор не обеспечивает защиту от повторной атаки.

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

Опции 2 и / или 3 требуются для API, которые делают больше, чем просто извлечение общедоступных данных, например, если они изменяют профили пользователей, публикуют контент или получают доступ к личной информации: см., Например, YouTube Страница аутентификации API данных , где OAuth упоминается как одна из возможных схем аутентификации.

Специально для варианта 1 ключ API здесь используется для отслеживания доступа пользователей к вашему API и, что наиболее важно, для ограничения доступа этими пользователями. Вариант 1 может не подходить для API, которые разрешают неограниченный доступ к данным.

(Это ответ, поскольку он слишком длинный, чтобы быть комментарием.)

0 голосов
/ 09 ноября 2011

Сервер содержит:

  • имя пользователя * * 1004
  • хэш пароля

Клиент отправляет:

  • имя пользователя
  • случайная строка
  • хеш (хэш пароля + случайная строка)

Когда клиенты вызывают сервер, сервер создает хэш пароля хэша (который он знает сам) + случайная строка (передается в GET вызывающим клиентом) и оценивает, соответствует ли он хэшу (заданному в GET вызывающим клиентом)

Еще лучше было бы создать 1 функцию, которая генерирует секретный хеш из (хэш пароля + nonce), где «nonce» (что-то случайное) также хранится на сервере. Затем сделайте возможным один раз вызвать сервер с именем пользователя + пароль, который возвращает секретный хеш; затем последующие вызовы зависят исключительно от имени пользователя + случайная строка + хеш (секретный хэш + случайная строка) с той же методологией, что и описанная выше, но секретным является пароль. Таким образом, даже если ваш секрет будет перехвачен и перевернут, ваш пропуск все равно будет в безопасности.

И, очевидно, хорошие алгоритмы хеширования: нет rot13 и даже только md5 сомнительно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...