Как принять аутентификацию на веб-API без SSL? - PullRequest
10 голосов
/ 22 декабря 2010

Я создаю веб-API, очень похожий на то, что StackOverflow предоставляет.

Однако в моем случае безопасность важна, поскольку данные являются частными.

  • Я должен использовать HTTP.
  • Я не могу использовать SSL.

Какие решения вы рекомендуете мне?

РЕДАКТИРОВАТЬ : аутентификация! = Шифрование

Ответы [ 4 ]

17 голосов
/ 23 декабря 2010

Почти каждый публичный API работает, передавая маркер аутентификации для каждого веб-запроса.

Этот токен обычно назначается одним из двух способов.

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

Другой способ - предоставить временный токен по запросу.Обычно у вас есть веб-метод, в котором вам передают имя пользователя / пароль, и вы возвращаете токен ограниченного использования, основанный на том, аутентифицирован ли он и авторизован ли для выполнения каких-либо действий API.

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

В качестве дополнительного примечания ваш комментарий о "безопасности важен", очевидно, не соответствует действительности.Если бы это было так, вы бы делали это по SSL.

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

16 голосов
/ 25 декабря 2010

Прежде всего, я предлагаю вам прочитать эту прекрасную статью: http://piwik.org/blog/2008/01/how-to-design-an-api-best-practises-concepts-technical-aspects/

Решение очень простое.Это комбинация Flickr-подобного API (на основе токенов) и метода аутентификации, используемого paiement gateway Я использую (очень безопасный), но вместо этого с личным паролем / солью.

Для предотвращениянеавторизованным пользователям использовать API без необходимости отправлять пароль в запросе (в моем случае, в открытом виде, поскольку SSL не существует), они должны добавить подпись , которая будет состоять из хеширования MD5 объединения частных и общедоступных значений:

  • Хорошо известные значения, такие как имя пользователя или даже маршрут API
  • Пропуск пользователя
  • Aуникальный код, сгенерированный пользователем (может использоваться только один раз)

Если мы запросим / api / route / и пароль будет kdf8 * s @ , подпись будет следующей:

string uniqueCode = Guid.NewGuid().ToString();
string signature = MD5.Compute("/api/route/kdf8*s@" + ticks);

URL-адрес HTTP-запроса будет:

string requestUrl = 
     string.Format("http://example.org/api/route/?code={0}&sign={1}", uniqueCode, signature);

На стороне сервера вам придется предотвращать любые новые запросы с тем жеуникальный кодЗапрещение любому злоумышленнику просто повторно использовать один и тот же URL в своих интересах.В этой ситуации я хотел избежать.

Поскольку я не хотел хранить код, который использовался пользователем API, я решил заменить его на ticks .Тики представляют собой число интервалов в 100 наносекунд, прошедших с 12:00:00 до полуночи 1 января 0001 года.

На стороне сервера я принимаю тики (метку времени) только с допуском + -3 минуты.(если клиент и сервер не синхронизированы по времени).Это означает, что потенциальный злоумышленник сможет использовать это окно для повторного использования URL-адреса, но не навсегда.Безопасность немного снижена, но все еще достаточно хороша для моего случая.

6 голосов
/ 22 декабря 2010

Краткий ответ: если предполагается, что его можно использовать через обычные клиенты (запросы браузера / AJAX), вы облажались.

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

HTTP обеспечивает только транспорт - без безопасной идентификации, без безопасной аутентификации и без безопасной авторизации.

Пример дыры в безопасности - простая HTTP-страница:

<script src="http://example.com/js/superstrongencryption.js"></script>
<script>
  encryptEverything();
</script>

Это может показаться безопасным, но имеет большой недостаток: у вас нет никаких гарантий, вообще ,что вы на самом деле загружаете файл superstrongencryption.js, который запрашиваете.С простым HTTP вы отправите запрос куда-нибудь , и что-то вернется.Нет никакого способа проверить, что он действительно пришел с example.com, и у вас нет никакого способа проверить, что это действительно правильный файл (а не просто function encryptEverything(){return true}).

Тем не менее, теоретически вы можетевстроить что-то очень похожее на SSL в свои HTTP-запросы и ответы: криптографически шифровать и подписывать каждый запрос, так же, как и каждый ответ.Для этого вам нужно написать специальный клиент (плюс, конечно, серверный код) - он не будет работать со стандартными браузерами.

1 голос
/ 22 декабря 2010

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

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