Digest Access Authentication — это один из методов, который клиент и сервер могут использовать для обмена учетными данными по HTTP. Этот метод использует комбинацию пароля и других битов информации для создания хеша MD5, который затем отправляется на сервер для аутентификации. Отправка хэша позволяет избежать проблем с отправкой пароля в виде открытого текста, что является недостатком базовой аутентификации доступа.
Дайджест-доступ был первоначально определен в RFC 2069 , а дополнительные усовершенствования безопасности были позже добавлены в RFC 2617, который следует считать текущим стандартом, если вы хотите реализовать этот метод самостоятельно. Мы рассмотрим оба в этой статье.
Проблема с базовой аутентификацией доступа
Во-первых, давайте рассмотрим базовую аутентификацию доступа. С вашим браузером вы запрашиваете какой-то объект, который требует от вас аутентификации. Если браузер не кэшировал учетные данные, которые вы уже предоставили, вы получите ответ «HTTP 401 Not Authorized», который содержит следующий заголовок:
WWW-Authenticate: Basic realm = "example.com"
Затем ожидается, что клиент / браузер ответит соответствующими учетными данными, чтобы получить доступ.
Имя пользователя и пароль соединяются вместе, например, «admin: p @ ssw0rd». Затем эта строка кодируется в Base64. Закодированная строка (YWRtaW46cEBzc3cwcmQ =) используется в заголовке авторизации, который отправляется обратно на сервер.
Авторизация: Basic YWRtaW46cEBzc3cwcmQ =
Когда сервер получает этот запрос, он замечает заголовок авторизации и применяет шаги в обратном порядке (декодирует и разделяет полученную строку), чтобы получить исходное имя пользователя и пароль. Затем процесс может выполнить любой поиск / проверку, необходимые с учетными данными.
Основная проблема здесь заключается в том, что Base64 является схемой передачи данных; это не схема хеширования или шифрования. Это также может быть простой текст. Digest Access Authentication пытается улучшить это, посылая пароль в виде хешированного значения, что намного труднее (не невозможно) восстановить значение открытого текста.
Работа с дайджест-аутентификацией доступа
При работе с Digest Access Authentication именно сервер должен сделать первый шаг, когда обнаружит, что клиент пытается получить доступ к ограниченной области. Есть несколько значений, которые сервер должен предоставить как часть заголовка WWW-Authenticate, который нужен клиенту.
Сервер генерирует значение, называемое nonce , которое должно быть уникальным для каждого запроса.
Рекомендуется, чтобы это значение было либо Base64, либо шестнадцатеричным, особенно потому, что оно будет заключено в двойные кавычки, и мы хотим убедиться, что в строке нет двойных кавычек. Одноразовый номер будет использоваться клиентом для генерации хэша для отправки обратно на сервер.
В PHP применение md5()
<?php
$nonce = md5(uniqid());
Следующее значение, необходимое клиенту, является непрозрачным . Это еще одна уникальная строка, сгенерированная сервером, которая, как ожидается, будет отправлена и возвращена клиентом без изменений.
<?php
$opaque = md5(uniqid());
Последнее значение realm — это просто строка для отображения пользователям, чтобы они знали, какое имя пользователя и пароль они должны предоставить. Он также используется клиентом для генерации хэша для отправки обратно на сервер.
<?php
$realm = 'Authorized users of example.com';
Все эти значения используются для составления директивы WWW-Authenticate и отправки в качестве ответа клиенту.
<?php
if (empty($_SERVER['PHP_AUTH_DIGEST']) {
header('HTTP/1.1 401 Unauthorized');
header(sprintf('WWW-Authenticate: Digest realm="%s", nonce="%s", opaque="%s"', $realm, $nonce, $opaque));
header('Content-Type: text/html');
echo '<p>You need to authenticate.</p>';
exit;
}
Когда клиент получает этот ответ, он должен вычислить возвращаемый хеш. Это достигается путем объединения имени пользователя, области и пароля и хеширования результата с помощью MD5 следующим образом:
- Вычислить
A1
MD5("username:realm:password")
- Вычислить
A2
MD5("requestMethod:requestURI")
- Вычислите окончательный хеш, известный как «response», как
MD5("A1:nonce:A2")
Клиент отправляет ответ обратно на сервер в заголовке авторизации и включает в себя имя пользователя, область, nonce, opaque, uri и вычисленный ответ.
Авторизация: дайджест имени пользователя = "% s", область = "% s", nonce = "% s", непрозрачный = "% s", uri = "% s", ответ = "% s" '
Обратите внимание, что области, nonce и opaque возвращаются на сервер без изменений.
Когда сервер получает ответ, те же шаги предпринимаются для вычисления серверной версии хэша. Если вычисленный хэш и полученные хэш-значения ответа совпадают, то запрос считается авторизованным. Это выглядит примерно так:
<?php
$A1 = md5("$username:$realm:$password");
$A2 = md5($_SERVER['REQUEST_METHOD'] . ":$uri");
$response = md5("$A1:$nonce:$A2");
Конечно, пароль пользователя никогда не передается на сервер. Чтобы выполнить поиск аутентификации из базы данных, можно сохранить значение A1. Имейте в виду, что сохраненный хэш становится недействительным, если вы когда-либо измените свою область.
Улучшение оригинальной спецификации доступа к дайджесту
Теперь, когда вы знакомы с работой Digest Access Authentication из RFC 2069, давайте обратим наше внимание на некоторые из улучшений, которые были добавлены в 2617: qop, nc и cnonce.
qop , или качество защиты, указывается в заголовке WWW-Authenticate и может иметь значение «auth» или «auth-int». Если директива qop не найдена или для нее установлено значение «auth», дайджест-доступ используется только для аутентификации клиента — режим по умолчанию, который вы видели до сих пор. Когда установлено значение «auth-int», делается попытка обеспечить некоторый уровень защиты целостности ответа, и клиент также должен включать тело запроса как часть дайджеста сообщения. Это позволяет серверу определить, был ли запрос фальсифицирован при передаче между клиентом с отступом и предполагаемым сервером.
Одноразовый номер клиента, или cnonce , похож на одноразовый номер, но генерируется клиентом. Cnonce фигурирует в дайджесте ответа, вычисленном клиентом, и его первоначальное значение передается на сервер, чтобы его можно было использовать для сравнения дайджестов. Это обеспечивает некоторую целостность ответа и взаимную аутентификацию, поскольку клиент и сервер могут доказать, что знают общий секрет. Когда сервер отправляет директиву qop, клиент должен включать значение cnonce.
Число одноразовых номеров nc — это шестнадцатеричное число запросов, отправленных клиентом с данным значением одноразового номера. Таким образом, сервер может защититься от повторных атак.
С улучшениями вычисление А2 и отклика происходит примерно так:
<?php
if ($qop == 'auth-int') {
$A2 = md5($_SERVER['REQUEST_METHOD'] . ":$uri:" . md5($respBody));
}
else {
$A2 = md5($_SERVER['REQUEST_METHOD'] . ":$uri");
}
$response = md5("$A1:$nonce:$nc:$cnonce:$qop:$A2");
Сильные и слабые стороны дайджест-аутентификации
Дайджест-доступ имеет некоторые преимущества по сравнению с базовой аутентификацией, так как базовая аутентификация использует открытый обмен текстовыми именами пользователей и паролями, что почти аналогично сообщению миру, какой у вас пароль. Дайджест-доступ передает хэшированное значение, а не сам пароль, поэтому он намного более безопасен, чем Basic Auth. Одноразовый номер сервера, который должен быть уникальным для каждого запроса, будет радикально изменять вычисляемый хеш при каждом новом запросе, а значение nc, предоставленное RFC 2617, помогает предотвратить атаки повторного воспроизведения, в результате чего злоумышленник может перехватить данные вашего запроса и « повторить »или повторить это как его собственный запрос.
У Digest Authentication также есть несколько недостатков. Когда RFC 2617 заменил исходную спецификацию, улучшения, которые были добавлены для обеспечения дополнительных мер безопасности между клиентом и сервером, стали совершенно необязательными, и дайджест-аутентификация будет продолжена в исходной форме RFC 2069, если она не будет реализована.
Другая проблема заключается в том, что MD5 не является сильным алгоритмом хеширования. Все, что нужно, — это время и процессор, чтобы грубо вернуть первоначальное значение к жизни. Bcrypt предпочтительнее, так как он более устойчив к атакам грубой силы. У сервера также нет возможности проверить личность запрашивающего клиента при использовании Digest Access Authentication. Это открывает возможность для человека в промежуточных атаках, когда клиента можно заставить поверить, что данный сервер действительно тот, кем он себя считает, но в итоге отправляет свои учетные данные для входа неизвестному объекту.
Лучше всего при аутентификации использовать SSL и шифровать пароли с помощью Bcrypt. Вы можете использовать обычную аутентификацию или механизм домашней аутентификации через SSL, но в ситуациях, когда SSL по какой-либо причине невозможен, Digest Access лучше простой базовой аутентификации и отправки паролей в виде простого текста через общедоступный Интернет.
В дополнение к этой статье на GitHub есть простой пример доступа к дайджесту HTTP RFC-2069 . Если вы тот человек, который любит исследовать и возиться, смело клонируйте его. Хорошим местом для начала упражнения является внесение необходимых изменений для работы с учетными записями, хранящимися в базе данных, вместо жестко закодированных учетных данных в сценарии (помните, что для дальнейшего использования вам потребуется рассчитать и сохранить A1 как хэш пароля пользователя). найдите логин), а затем улучшите его с помощью функций RFC-2617. После этого вы получите достаточно четкое представление об аутентификации доступа к дайджесту HTTP.
Резюме
К настоящему времени у вас должно быть представление о доступных методах аутентификации HTTP.
Базовая аутентификация является самой простой в реализации, а также наименее безопасной. Имена пользователей и пароли кодируются в Base64, но эффективно отправляются на сервер в виде простого текста.
Дайджест-аутентификация улучшает базовый метод, отправляя данные аутентификации через MD5. Хотя MD5 все еще не является надежным алгоритмом шифрования паролей, его гораздо сложнее декодировать, чем простой текст / метод Base64 базовой аутентификации. В первоначальном виде все еще были проблемы со средним уровнем атаки и неспособностью подтвердить идентичность сервера, но эти недостатки были исправлены в более поздних версиях RFC.
SSL — это самый современный и безопасный способ отправки данных аутентификации пользователя через общедоступный Интернет. Но когда SSL недоступен, используйте дайджест поверх обычной аутентификации.
Изображение через Fotolia