RFC 2617 | HTTP-аутентификация: базовая и дайджест-аутентификация

RFC 2617 | HTTP-аутентификация: базовая и дайджест-аутентификация

Аннотация

«HTTP/1.0» включает в себя спецификацию для схемы проверки подлинности базового доступа (Basic Access Authentication). Эта схема не считается безопасным методом аутентификации пользователя (если только не используется в сочетании с какой-либо внешней защищенной системой, такой как SSL [5]), поскольку имя пользователя и пароль передаются по сети в виде открытого текста.

Скачать оригинальный документ на английском языке RFC 2617 PDF

Этот документ также предоставляет спецификацию для структуры аутентификации HTTP, исходной Базовой схемы аутентификации (Basic authentication scheme) и схемы, основанной на криптографических хешах (cryptographic hashes), называемой «Digest Access Authentication» (дайджест-аутентификацией доступа). Поэтому он также предназначен для замены RFC 2069 [6]. Некоторые дополнительные элементы, указанные в RFC 2069, были удалены из этой спецификации из-за проблем, обнаруженных с момента ее публикации; другие совместимые элементы были добавлены для совместимости, эти новые элементы были сделаны необязательными, но настоятельно рекомендуются.

Как и «Basic«, «Digest» аутентификация доступа проверяет, что обе стороны коммуникации знают общий секрет (пароль — password); в отличие от Basic, эта проверка может быть проведена без отправки пароля в открытом виде, что является самым большим недостатком Basic. Как и в большинстве других протоколов аутентификации, наибольшие источники рисков обычно находятся не в самом базовом протоколе, а в политиках и процедурах, связанных с его использованием.

 

Дата создания документа

Июнь 1999 года

Оглавление

1. Аутентификация доступа
1.1. Опора на спецификацию HTTP/1.1
1.2. Access Authentication Framework
2. Базовая схема аутентификации
3. Дайджест схема аутентификации доступа
3.1. Введение
3.1.1. Цель
3.1.2. Общая эксплуатация
3.1.3. Представление значений дайджеста
3.1.4. Ограничения
3.2. Спецификация дайджест-заголовков
3.2.1. Заголовок ответа WWW-Authenticate
3.2.2. Заголовок запроса Authorization
3.2.2.1 Request-Digest
3.2.2.2 A1
3.2.2.3 A2
3.2.2.4 Директивные значения и строка в кавычках
3.2.2.5 Различные соображения
3.2.3. Заголовок Authentication-Info
3.3. Дайджест Операция
3.4. Согласование протокола безопасности
3.5. Пример
3.6. Прокси-аутентификация и прокси-авторизация
4. Соображения безопасности
4.1. Аутентификация клиентов с использованием базовой аутентификации
4.2. Аутентификация клиентов с использованием дайджест-аутентификации
4.3. Ограниченные значения одноразового использования
4.4. Сравнение дайджеста с базовой аутентификацией
4.5. Повторные атаки
4.6. Слабость, созданная несколькими схемами аутентификации
4.7. Атаки онлайн-словаря
4.8. Человек посередине
4.9. Выбранные атаки открытым текстом
4.10. Атаки по предварительно вычисленным словарям
4.11. Групповые атаки методом грубой силы
4.12. Подмена поддельных серверов
4.13. Хранение паролей
4.14. Резюме
5. Пример реализации
6. Благодарности
7. Ссылки
8. Авторы и адреса
9. Полное заявление об авторских правах

 

Статус этой заметки

Этот документ определяет протокол отслеживания стандартов Интернета для интернет-сообщества и запрашивает обсуждение и предложения по улучшению. Пожалуйста, обратитесь к текущей редакции «Официальных стандартов протокола Интернета» (STD 1) для ознакомления с состоянием стандартизации и статусом этого протокола.

Распространение этой заметки не ограничено.

 

Уведомление об авторских правах

Copyright (C) Интернет-общество (1999). Все права защищены.

 

1. Аутентификация доступа

1.1. Опора на спецификацию HTTP/1.1

Данная спецификация является дополнением к спецификации HTTP/1.1 [2]. Она использует расширенный раздел 2.1 BNF этого документа и опирается как на нетерминалы (non-terminals), определенные в этом документе, так и на другие аспекты спецификации HTTP/1.1.

1.2. Access Authentication Framework (Структура Проверки Подлинности Доступа)

HTTP предоставляет простой механизм аутентификации «запрос-ответ«, который МОЖЕТ использоваться сервером для запроса клиента и клиентом для предоставления информации аутентификации. Он использует расширяемый «токен без учета регистра» (case-insensitive token) для идентификации схемы аутентификации, за которым следует разделенный запятыми список пар «атрибут-значение«, которые содержат параметры, необходимые для достижения аутентификации через эту схему.

auth-scheme = token
auth-param = token "=" ( token | quoted-string )

Ответное сообщение 401 (Unauthorized — Неавторизован) используется сервером происхождения для вызова авторизации пользовательского агента. Этот ответ ДОЛЖЕН включать поле заголовка «WWW-Authenticate», содержащее, по крайней мере, один запрос, применимый к запрашиваемому ресурсу. Ответное сообщение 407 (Proxy Authentication Required — Требуется проверка подлинности прокси-сервера) используется прокси-сервером для вызова авторизации клиента и ДОЛЖНО включать поле заголовка «Proxy-Authenticate», содержащее, по крайней мере, один запрос, применимый к прокси-серверу для запрошенного ресурса.

challenge = auth-scheme 1*SP 1#auth-param

Примечание. Пользовательским Агентам нужно будет проявить особую осторожность при разборе значения поля заголовка «WWWAuthenticate» или «Proxy-Authenticate», если оно содержит более одного запроса или если предусмотрено более одного поля заголовка «WWW-Authenticate», так как содержимое запроса может само по себе содержать разделенный запятыми список параметров аутентификации.

Область параметров аутентификации (authentication parameter realm) определена для всех схем аутентификации:

realm = "realm" "=" realm-value
realm-value = quoted-string

Директива области «realm directive» (без учета регистра) требуется для всех схем аутентификации, которые вызывают вызов. Значение области «realm value» (с учетом регистра) в сочетании с каноническим корневым URL-адресом («absoluteURI» для сервера, чей «abs_path» пуст; см. Раздел 5.1.2 из [2]) сервера, к которому осуществляется доступ, определяет пространство защиты (protection space). Эти области позволяют разделить защищенные ресурсы на сервере на набор защитных пространств, каждое со своей собственной схемой аутентификации и / или базой данных авторизации (authorization database). Значение области «realm value» — это строка, обычно назначаемая исходным сервером, которая может иметь дополнительную семантику, специфичную для схемы аутентификации. Обратите внимание, что может быть несколько проблем с одной и той же схемой аутентификации, но разными областями.

Пользовательский агент (user agent), который желает аутентифицировать себя на исходном сервере — обычно, но не обязательно, после получения 401 (Unauthorized — Неавторизован) — МОЖЕТ сделать это, включив поле заголовка авторизации «Authorization» в запрос. Клиент, который хочет аутентифицировать себя с прокси-сервером — обычно, но не обязательно, после получения 407 (Proxy Authentication Required — Требуется аутентификация прокси-сервера) — МОЖЕТ сделать это, включив в заголовок поле Proxy-Authorization. Как значение поля «Authorization», так и значение поля «Proxy-Authorization» состоят из учетных данных, содержащих информацию об аутентификации клиента для области запрашиваемого ресурса. Пользовательский агент ДОЛЖЕН выбрать использование одной из проблем с самой мощной схемой аутентификации, которую он понимает, и запрашивать учетные данные у пользователя на основе этой задачи.

credentials = auth-scheme #auth-param

Обратите внимание, что многие браузеры распознают только «Basic» и требуют, чтобы это была первая представленная схема аутентификации. Серверы должны включать только «Basic«, если это минимально приемлемо.

Область защиты определяет домен, к которому могут автоматически применяться учетные данные. Если предыдущий запрос был авторизован, те же учетные данные МОГУТ использоваться повторно для всех других запросов в этом защитном пространстве в течение периода времени, определенного схемой аутентификации, параметрами и / или предпочтениями пользователя. Если иное не определено схемой аутентификации, одно пространство защиты не может выходить за пределы области действия своего сервера.

Если исходный сервер не желает принимать учетные данные, отправленные с запросом, он ДОЛЖЕН вернуть ответ 401 (Неавторизован). Ответ ДОЛЖЕН включать поле заголовка «WWW-Authenticate», содержащее, по крайней мере, одну (возможно, новую) задачу, применимую к запрашиваемому ресурсу. Если прокси-сервер не принимает учетные данные, отправленные с запросом, он ДОЛЖЕН вернуть 407 (Требуется проверка подлинности прокси-сервера). Ответ ДОЛЖЕН включать поле заголовка «Proxy-Authenticate», содержащее (возможно, новую) задачу, применимую к прокси для запрошенного ресурса.

Протокол HTTP не ограничивает приложения этим простым механизмом «запроса-ответа» для аутентификации доступа. Могут использоваться дополнительные механизмы, такие как шифрование на транспортном уровне (encryption at the transport level) или инкапсуляция сообщений (message encapsulation), и с дополнительными полями заголовка, определяющими информацию аутентификации. Однако эти дополнительные механизмы не определены в данной спецификации.

Прокси ДОЛЖНЫ быть полностью прозрачными в отношении аутентификации пользовательского агента исходными серверами. То есть они должны пересылать заголовки «WWW-Authenticate» и «Authorization» без изменений и следовать правилам, изложенным в разделе 14.8 из [2]. Поля заголовка «Proxy-Authenticate» и «Proxy-Authorization» являются заголовками переходов (см. Раздел 13.5.1 из [2]).

 

2. Базовая схема аутентификации (Basic Authentication Scheme)

«Базовая» схема аутентификации (Basic Authentication Scheme) основана на модели, согласно которой клиент должен аутентифицировать себя с помощью идентификатора пользователя и пароля для каждой области. Значение области следует считать непрозрачной строкой, которую можно сравнить только на равенство с другими областями на этом сервере. Сервер будет обслуживать запрос только в том случае, если он сможет подтвердить идентификатор пользователя и пароль для пространства защиты запроса-URI. Там нет дополнительных параметров аутентификации.

Для «Basic» вышеупомянутая структура используется следующим образом:

challenge = "Basic" realm
credentials = "Basic" basic-credentials

После получения неавторизованного запроса на URI в пределах пространства защиты сервер источника МОЖЕТ ответить на запрос, подобный следующему:

WWW-Authenticate: Basic realm="WallyWorld"

где «WallyWorld» — это строка, назначенная сервером для идентификации защитного пространства «Request-URI». Прокси может ответить тем же вызовом, используя поле заголовка «Proxy-Authenticate».

Чтобы получить авторизацию, клиент отправляет идентификатор пользователя (userid) и пароль (password), разделенные одним двоеточием («:»), в кодированной строке base64 [7] в учетных данных.

basic-credentials = base64-user-pass
base64-user-pass = <base64 [4] encoding of user-pass, except not limited to 76 char/line>
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT

Идентификаторы могут быть чувствительны к регистру.

Если пользовательский агент желает отправить ИД пользователя «Aladdin» и пароль «open sesame«, он будет использовать следующее поле заголовка:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Клиент ДОЛЖЕН предположить, что все пути на глубине или глубже, чем последний символический элемент в поле пути Request-URI, также находятся в пределах пространства защиты, заданного значением базовой области текущего запроса. Клиент МОЖЕТ превентивно отправить соответствующий заголовок авторизации с запросами ресурсов в этом пространстве без получения другого запроса от сервера. Аналогичным образом, когда клиент отправляет запрос прокси-серверу, он может повторно использовать идентификатор пользователя и пароль в поле заголовка «Proxy-Authorization» без получения другого запроса от прокси-сервера. См. Раздел 4 для соображений безопасности, связанных с обычной аутентификацией.

 

3. Дайджест схема Аутентификации Доступа (Digest Access Authentication Scheme)

3.1. Введение

3.1.1. Цель

Протокол, называемый «HTTP/1.0», включает в себя спецификацию для схемы проверки подлинности базового доступа (Basic Access Authentication scheme) [1]. Эта схема не считается безопасным методом аутентификации пользователя, поскольку имя пользователя и пароль передаются по сети в незашифрованном виде. В этом разделе приведена спецификация для схемы, которая не отправляет пароль в виде открытого текста, называемой «Digest Access Authentication» (дайджест-аутентификация доступа).

Дайджест схема аутентификации доступа не предназначена для того, чтобы быть полным ответом на необходимость обеспечения безопасности во Всемирной паутине (World Wide Web). Эта схема не обеспечивает шифрование содержимого сообщения. Цель состоит в том, чтобы просто создать метод аутентификации доступа, который позволяет избежать наиболее серьезных недостатков обычной аутентификации.

3.1.2. Общая эксплуатация

Как и «Basic» аутентификация доступа, схема «Digest» основана на простой парадигме «запрос-ответ». Схема «Digest» бросает вызов одноразовому значению. Допустимый ответ содержит контрольную сумму (по умолчанию контрольную сумму MD5) имени пользователя, пароля, заданного значения «nonce«, метода HTTP и запрошенного URI. Таким образом, пароль никогда не отправляется в открытом виде. Как и в случае с «Basic» схемой, имя пользователя и пароль должны быть заранее установлены каким-либо образом, не рассматриваемым в этом документе.

3.1.3. Представление дайджест-значений

Необязательный заголовок позволяет серверу указать алгоритм, используемый для создания контрольной суммы или дайджеста. По умолчанию используется алгоритм MD5, и это единственный алгоритм, описанный в этом документе. Для целей этого документа дайджест MD5 из 128 битов представлен как 32 печатных символа ASCII. Биты в 128-битном дайджесте преобразуются из старшего значащего в младший значащий бит по четыре бита за раз в их представление ASCII следующим образом. Каждые четыре бита представлены знакомыми шестнадцатеричными обозначениями из символов «0123456789abcdef«. Таким образом, двоичный код 0000 представлен символом «0»,а 0001 символом «1» и т. д. Вплоть до представления 1111 в виде «f».

3.1.4. Ограничения

Схема дайджест-аутентификации (Digest authentication scheme), описанная в этом документе, страдает многими известными ограничениями. Она предназначена для замены обычной аутентификации и ничего более. Это система, основанная на пароле, и (на стороне сервера) страдает от всех тех же проблем, что и любая система паролей. В частности, в этом протоколе не предусмотрена первоначальная безопасная договоренность между пользователем и сервером для установления пароля пользователя.

Пользователи и разработчики должны знать, что этот протокол не так безопасен, как «Kerberos«, и не так безопасен, как любая схема закрытого ключа на стороне клиента. Тем не менее, это лучше, чем ничего, лучше, чем то, что обычно используется с «telnet» и «ftp«, и лучше, чем обычная аутентификация «Basic«.

3.2. Спецификация дайджест-заголовков

Дайджест схема аутентификации доступа концептуально аналогична базовой схеме. Форматы измененной строки заголовка «WWW-Authenticate» и строки заголовка «Authorization» указаны ниже. Кроме того, указывается новый заголовок «Authentication-Info«.

3.2.1. Заголовок ответа «WWW-Authenticate»

Если сервер получает запрос на объект, защищенный от доступа, и приемлемый заголовок авторизации не отправляется, сервер отвечает кодом состояния «401 неавторизован» и заголовком «WWW-Authenticate» в соответствии с определенной выше структурой, которая для Схемы дайджеста используется следующим образом:

challenge = "Digest" digest-challenge

digest-challenge = 1#( realm | [ domain ] | nonce | [ opaque ] |[ stale ] | [ algorithm ] | [ qop-options ] | [auth-param] )

domain = "domain" "=" <"> URI ( 1*SP URI ) <">
URI = absoluteURI | abs_path
nonce = "nonce" "=" nonce-value
nonce-value = quoted-string
opaque = "opaque" "=" quoted-string
stale = "stale" "=" ( "true" | "false" )
algorithm = "algorithm" "=" ( "MD5" | "MD5-sess" | token )
qop-options = "qop" "=" <"> 1#qop-value <">
qop-value = "auth" | "auth-int" | token

Смыслы значений директив заголовка ответа «WWW-Authenticate«, использованных выше, следующие:

realm — область

Строка, отображаемая пользователям, чтобы они знали, какое имя пользователя и пароль использовать. Эта строка должна содержать как минимум имя хоста, выполняющего аутентификацию, и может дополнительно указывать группу пользователей, которые могут иметь доступ. Примером может быть:

registered_users@gotham.news.com

domain — домен

Цитированный разделенный пробелами список URI, как указано в RFC XURI [7], которые определяют пространство защиты (protection space). Если URI является «abs_path«, он относится к каноническому корневому URL (см. Раздел 1.2 выше) сервера, к которому осуществляется доступ. Абсолютный URI (absoluteURI) в этом списке может относиться к серверу, отличному от того, к которому осуществляется доступ. Клиент может использовать этот список, чтобы определить набор URI, для которых может быть отправлена одна и та же информация аутентификации: любой URI, который имеет URI в этом списке в качестве префикса (после того, как оба были сделаны абсолютными), можно считать находящимся в одном и том же защитном пространстве. Если эта директива (domain) опущена или ее значение пусто, клиент должен предположить, что пространство защиты состоит из всех URI на отвечающем сервере. Эта директива (domain) не имеет смысла в заголовках «Proxy-Authenticate«, для которых защитным пространством всегда является весь прокси; если он присутствует, его следует игнорировать.

nonce — данное время

«nonce» — это указанная сервером строка данных, которая должна генерироваться уникальным образом каждый раз при получении ответа 401. Рекомендуется, чтобы строкой nonce были base64 или шестнадцатеричные данные. В частности, поскольку строка nonce передается в строках заголовка в виде строки в кавычках, символ двойной кавычки не допускается.

Содержимое одноразового номера зависит от реализации. Качество реализации зависит от удачного выбора. Одноразовый номер может, например, быть сконструирован как кодировка base 64

time-stamp H(time-stamp ":" ETag ":" private-key)

где отметка времени (time-stamp) — это сгенерированное сервером время или другое неповторяющееся значение, ETag — это значение заголовка HTTP ETag, связанного с запрошенным объектом, а закрытый ключ (private-key) — это данные, известные только серверу. В случае одноразового номера (nonce) этой формы сервер будет пересчитывать часть хеш-функции после получения заголовка аутентификации клиента и отклонять запрос, если он не соответствует одноразовому номеру из этого заголовка или если значение метки времени (time-stamp) не является достаточно недавним. Таким образом, сервер может ограничить время действия одноразового номера. Включение ETag предотвращает запрос воспроизведения для обновленной версии ресурса. (Примечание: включение IP-адреса клиента в одноразовый номер (nonce’s validity), по-видимому, предложит серверу возможность ограничить повторное использование одноразового номера (nonce) тем же клиентом, который изначально получил его. Однако это нарушит работу прокси-ферм (proxy farms), где запросы поступающие от одного пользователя часто проходят через различные прокси-серверы в ферме. Кроме того, подделка IP-адреса не так сложна.)

Реализация может решить не принимать ранее использованный одноразовый номер (nonce) или ранее использованный дайджест, чтобы защитить от атаки воспроизведения (replay attack). Либо реализация может выбрать использование одноразовых номеров (nonce) или дайджестов для запросов POST или PUT и отметки времени для запросов GET. Для получения более подробной информации о проблемах см. Раздел 4 этого документа.

Одноразовый номер (nonce) непрозрачен (opaque) для клиента.

opaque — непрозрачный

«opaque» — это строка данных, указанная сервером, которая должна быть возвращена клиентом без изменений в заголовке «Authorization» последующих запросов с URI в том же пространстве защиты (protection space). Рекомендуется, чтобы этой строкой были base64 или шестнадцатеричные данные.

stale — несвежий

Флаг «stale» указывает, что предыдущий запрос от клиента был отклонен, поскольку значение «nonce» устарело. Если stale имеет значение TRUE (без учета регистра), клиент может захотеть просто повторить запрос с новым зашифрованным ответом, без повторного запроса пользователя для нового имени пользователя и пароля. Сервер должен устанавливать в качестве устаревшего значение TRUE, если он получает запрос, для которого одноразовый номер «nonce» является недействительным, но с действительным дайджестом (digest) для этого одноразового номера (указывая, что клиент знает правильное имя пользователя/пароль). Если stale является FALSE, или что-то отличное от TRUE, или если директива stale отсутствует, имя пользователя и/или пароль недействительны, и должны быть получены новые значения.

algorithm — алгоритм

«algorithm» — это строка, обозначающая пару алгоритмов, используемых для создания дайджеста (digest) и контрольной суммы (checksum). Если этого нет, предполагается, что это «MD5». Если алгоритм не понят, вызов следует игнорировать (и использовать другой, если их больше одного).

В этом документе строка, полученная путем применения алгоритма дайджеста к данным «data» с секретом «secret», будет обозначаться как KD(secret, data), а строка, полученная путем применения алгоритма контрольной суммы к данным «data», будет обозначается H(data). Обозначение unq(X) означает значение строки X в кавычках без окружающих кавычек.

Для алгоритмов «MD5» и «MD5-sess»

H(data) = MD5(data)

и

KD(secret, data) = H(concat(secret, ":", data))

то есть дайджест (digest) — это MD5 секрета (secret), соединенного с двоеточием, соединенным с данными (data). Алгоритм «MD5-sess» предназначен для обеспечения эффективных сторонних серверов аутентификации; о разнице в использовании см. описание в разделе 3.2.2.2.

qop-options — Варианты качества защиты

Директива «qop-options» является необязательной, но сделана так только для обратной совместимости с RFC 2069 [6]; она ДОЛЖНА использоваться всеми реализациями, совместимыми с этой версией схемы дайджеста. Если присутствует, строка «qop-options» в кавычках одного или нескольких токенов, указывающая значения «quality of protection» (качества защиты), поддерживаемые сервером. Значение «auth» указывает на аутентификацию; значение «auth-int» указывает аутентификацию с защитой целостности; см. описание ниже для расчета значения директивы ответа для применения этого выбора. Нераспознанные параметры ДОЛЖНЫ игнорироваться.

auth-param — параметры аутентификации

Директива «auth-param» допускает будущие расширения. Любая нераспознанная директива ДОЛЖНА игнорироваться.

3.2.2. Заголовок запроса «Authorization»

Ожидается, что клиент будет повторять запрос, передавая строку заголовка «Authorization«, которая определяется в соответствии с описанной выше структурой, используемой следующим образом.

credentials = "Digest" digest-response
digest-response = 1#( username | realm | nonce | digest-uri | response | [ algorithm ] | [cnonce] | [opaque] | [message-qop] | [nonce-count] | [auth-param] )

username = "username" "=" username-value
username-value = quoted-string
digest-uri = "uri" "=" digest-uri-value
digest-uri-value = request-uri ; As specified by HTTP/1.1
message-qop = "qop" "=" qop-value
cnonce = "cnonce" "=" cnonce-value
cnonce-value = nonce-value
nonce-count = "nc" "=" nc-value
nc-value = 8LHEX
response = "response" "=" request-digest
request-digest = <"> 32LHEX <">
LHEX = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "a" | "b" | "c" | "d" | "e" | "f"

Значения полей непрозрачности (opaque) и алгоритма (algorithm) должны быть такими, которые указаны в заголовке ответа «WWW-Authenticate» для запрашиваемого объекта.

Смыслы значений директив заголовка запроса «Authorization«, использованных выше, следующие:

response — ответ

Строка из 32 шестнадцатеричных цифр, вычисленная как определено ниже, которая доказывает, что пользователь знает пароль.

username — имя пользователя

Имя пользователя в указанной области (realm).

digest-uri — дайджест-унифицированный индикатор ресурса

URI из Request-URI строки запроса; здесь дублируется, потому что прокси разрешено изменять строку запроса при передаче.

qop — качество защиты

Указывает, какое «качество защиты» («quality of protection«) клиент применил к сообщению. Если присутствует, то его значение ДОЛЖНО быть одной из альтернатив, которые сервер указал, что он поддерживает в заголовке «WWW-Authenticate«. Эти значения влияют на вычисление дайджеста запроса (request-digest). Обратите внимание, что это один токен, а не список альтернативных вариантов, как в «WWW-Authenticate«. Эта директива является необязательной, чтобы сохранить обратную совместимость с минимальной реализацией RFC 2069 [6], но ее СЛЕДУЕТ использовать, если сервер указал, что «qop» поддерживается путем предоставления директивы «qop» в поле заголовка WWW-Authenticate.

cnonce

«cnonce» ДОЛЖНО быть указано, если отправлена директива «qop» (см. выше), и НЕ ДОЛЖНО быть указано, если сервер не отправил директиву «qop» в поле заголовка «WWW-Authenticate». Значение cnonce — это непрозрачное строковое значение в кавычках, предоставляемое клиентом и используемое клиентом, и сервером, чтобы избежать выбранных атак открытым текстом (plaintext attacks), обеспечить взаимную аутентификацию и обеспечить некоторую защиту целостности сообщения. См. Описания ниже вычисления значений дайджеста ответа и дайджеста запроса (request-digest).

nonce-count

«nonce-count» ДОЛЖНО быть указано, если отправлена директива «qop» (см. выше), и НЕ ДОЛЖНО быть указано, если сервер не отправил директиву «qop» в поле заголовка «WWW-Authenticate». Nc-значение (nc-value) — это шестнадцатеричное количество запросов (включая текущий запрос), которые клиент отправил со значением «nonce» в этом запросе. Например, в первом запросе, отправленном в ответ на данное значение «nonce», клиент отправляет «nc =00000001». Цель этой директивы состоит в том, чтобы позволить серверу обнаруживать повторы запросов, поддерживая свою собственную копию этого счетчика — если одно и то же значение «nc» отображается дважды, тогда запрос является воспроизведением. См. Описание ниже построения значения дайджест-запроса (request-digest).

auth-param

Директива «auth-param» допускает будущие расширения. Любая нераспознанная директива ДОЛЖНА игнорироваться.


Если директива или ее значение неверны или отсутствуют обязательные директивы, правильным ответом является 400 (Bad Request). Если «request-digest» является недопустимым, то следует регистрировать ошибку входа в систему, поскольку повторные ошибки входа в систему с одного клиента могут указывать на то, что злоумышленник пытается угадать пароли.

Определение запроса-дайджеста (request-digest) выше указывает кодировку для его значения. Следующие определения показывают, как вычисляется значение.

3.2.2.1. Request-Digest

Если значение «qop» равно «auth» или «auth-int«:

request-digest = <"> < KD ( H(A1), unq(nonce-value)
                              ":" nc-value
                              ":" unq(cnonce-value)
                              ":" unq(qop-value)
                              ":" H(A2)
                          ) <">

Если директива «qop» отсутствует (эта конструкция предназначена для совместимости с RFC 2069):

request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">

Ниже приведены определения для «А1» и «А2«.

3.2.2.2. A1

Если значение директивы «algorithm» равно «MD5» или не указано, то A1:

A1 = unq(username-value) ":" unq(realm-value) ":" passwd

где

passwd = < user’s password >

Если значение директивы «algorithm» равно «MD5-sess», то A1 вычисляется только один раз — по первому запросу клиента после получения запроса «WWW-Authenticate» от сервера. Он использует одноразовый номер сервера из этой задачи и первое значение одноразового номера клиента для построения A1 следующим образом:

A1 = H( unq(username-value) ":" unq(realm-value)
        ":" passwd )
        ":" unq(nonce-value) ":" unq(cnonce-value)

Это создает «session key» (ключ сеанса) для аутентификации последующих запросов и ответов, который отличается для каждого «authentication session» (сеанса аутентификации), тем самым ограничивая количество материала, хэшированного с любым одним ключом. (Примечание: см. Дальнейшее обсуждение сеанса аутентификации в разделе 3.3.) Поскольку серверу нужно только использовать хэш учетных данных пользователя для создания значения A1, эту конструкцию можно использовать вместе со сторонней службой аутентификации, чтобы веб-серверу не потребовалось фактическое значение пароля. Спецификация такого протокола выходит за рамки этой спецификации.

3.2.2.3. A2

Если значение директивы «qop» равно «auth» или не указано, то A2 — это:

A2 = Method ":" digest-uri-value

Если значение «qop» равно «auth-int«, то A2:

A2 = Method ":" digest-uri-value ":" H(entity-body)
3.2.2.4. Значения директив и строка в кавычках

Обратите внимание, что значение многих из директив, таких как «username-value«, определяется как «quoted-string» (строка в кавычках). Однако запись «unq» указывает, что окружающие кавычки удаляются при формировании строки A1. Таким образом, если заголовок авторизации включает в себя поля

username = "Mufasa", realm=myhost@testrealm.com

и у пользователя Mufasa есть пароль «Circle Of Life», тогда H (A1) будет H (Mufasa:myhost@testrealm.com:Circle Of Life) без кавычек в переваренной строке.

Запрещено использовать пробелы в любой из строк, к которым применяется дайджест-функция H (), если только этот пробел не существует в строках в кавычках или в теле сущности, содержимое которого составляет строку, подлежащую обработке. Например, строка A1, показанная выше, должна быть

Mufasa:myhost@testrealm.com:Circle Of Life

без пробелов по обе стороны от двоеточий, но с пробелом между словами, используемыми в значении пароля. Аналогично, другие строки, перевариваемые с помощью H (), не должны иметь пробелов по обе стороны от двоеточий, которые разграничивают их поля, если только этот пробел не был в цитируемых строках или теле сущности, которое переваривалось.

Также обратите внимание, что если применяется защита целостности (qop=auth-int), H (entity-body) — это хэш тела объекта, а не тела сообщения — он вычисляется до того, как отправитель и после которого будет применено любое кодирование передачи он был удален получателем. Обратите внимание, что это включает составные границы и встроенные заголовки в каждой части любого составного типа контента.

3.2.2.5. Различные соображения

Значение «Method» (Метод) — это метод HTTP-запроса, как указано в разделе 5.1.1 [2]. Значение «request-uri» — это Request-URI из строки запроса, как указано в разделе 5.1.2 в [2]. Это может быть звёздочка «*», «absoluteURL» или «abs_path», как указано в разделе 5.1.2 [2], но оно ДОЛЖНО совпадать с Request-URI. В частности, он ДОЛЖЕН быть «absoluteURL», если Request-URI является «absoluteURL». «Cnonce-value» — это необязательное значение, выбранное клиентом, целью которого является предотвращение выбранных атак открытым текстом.

Сервер аутентификации должен убедиться, что ресурс, указанный в директиве «uri«, совпадает с ресурсом, указанным в строке запроса; в противном случае сервер ДОЛЖЕН вернуть ошибку 400 Bad Request. (Поскольку это может быть признаком атаки, разработчики сервера могут захотеть занести в журнал такие ошибки.) Цель дублирования информации из URL-адреса запроса в этом поле состоит в том, чтобы справиться с возможностью того, что промежуточный прокси-сервер может изменить линию-запрос клиента. Этот измененный (но предположительно семантически эквивалентный) запрос не приведет к тому же дайджесту (digest), что и рассчитанный клиентом.

Разработчики должны знать, как аутентифицированные транзакции взаимодействуют с общими кэшами. Протокол HTTP/1.1 указывает, что когда общий кэш (см. Раздел 13.7 в [2]) получил запрос, содержащий заголовок «Authorization» и ответ от передачи этого запроса, он НЕ ДОЛЖЕН возвращать этот ответ в качестве ответа на любой другой запрос, если в ответе не присутствует одна из двух директив «Cache-Control» (см. раздел 14.9 из [2]). Если исходный ответ содержал директиву Cache-Control «must-revalidate», кеш МОЖЕТ использовать объект этого ответа при ответе на последующий запрос, но ДОЛЖЕН сначала подтвердить его на исходном сервере, используя заголовки запроса из нового запроса, чтобы позволить исходному серверу аутентифицировать новый запрос. В качестве альтернативы, если исходный ответ содержал директиву «public» Cache-Control, объект ответа МОЖЕТ быть возвращен в ответ на любой последующий запрос.

3.2.3. Заголовок Authentication-Info

Заголовок «Authentication-Info» используется сервером для передачи некоторой информации об успешной аутентификации в ответе.

AuthenticationInfo = "Authentication-Info" ":" auth-info
auth-info = 1#(nextnonce | [ message-qop ] | [ response-auth ] | [ cnonce ] | [nonce-count] )
nextnonce = "nextnonce" "=" nonce-value
response-auth = "rspauth" "=" response-digest
response-digest = <"> *LHEX <">

nextnonce

Значение директивы «nextnonce» — это тот раз, когда сервер желает, чтобы клиент использовал его для будущего ответа аутентификации. Сервер может отправить заголовок Authentication-Info с полем nextnonce в качестве средства реализации одноразовых или иным образом изменяющихся одноразовых номеров (nonces). Если поле nextnonce присутствует, клиент ДОЛЖЕН использовать его при создании заголовка Authorization для своего следующего запроса. Невыполнение этого требования клиентом может привести к запросу на повторную аутентификацию с сервера с помощью «stale=TRUE».

Реализации сервера должны тщательно учитывать последствия использования этого механизма для производительности; конвейерные запросы будут невозможны, если каждый ответ содержит директиву nextnonce, которая должна использоваться при следующем запросе, полученном сервером. Следует учитывать компромиссы между производительностью и безопасностью, позволяя использовать старое одноразовое значение в течение ограниченного времени, чтобы разрешить конвейеризацию запросов. Использование одноразового номера (nonce-count) может сохранить большинство преимуществ безопасности нового одноразового номера сервера без вредного влияния на конвейерную обработку.

message-qop

Директива «message-qop» указывает параметры «качества защиты» («quality of protection»), применяемые к ответу сервера. Значение «auth» указывает на аутентификацию; значение «auth-int» указывает на аутентификацию с защитой целостности. Сервер ДОЛЖЕН использовать в ответе то же значение для директивы «message-qop«, которое было отправлено клиентом в соответствующем запросе.

Необязательный дайджест ответа в директиве «response-auth» поддерживает взаимную аутентификацию — сервер подтверждает, что знает секрет пользователя, и с помощью (qop=auth-int) также обеспечивает ограниченную защиту целостности ответа. Значение «response-digest» рассчитывается так же, как и для «request-digest» в заголовке авторизации, за исключением того, что если «qop=auth» или не указано в заголовке авторизации для запроса, A2

A2 = ":" digest-uri-value

и если «qop=auth-int«, то A2

A2 = ":" digest-uri-value ":" H(entity-body)

где «digest-uri-value» — это значение директивы «uri» в заголовке авторизации в запросе. «Cnonce-value» и «nc-value» ДОЛЖНЫ быть теми для запроса клиента, на который это сообщение является ответом. Директивы «response-auth», «cnonce» и «nonce-count» ДОЛЖНЫ БЫТЬ присутствовать, если указано «qop=auth» или «qop=auth-int».

Заголовок «Authentication-Info» разрешен в трейлере HTTP-сообщения, переданного с помощью кодирования передачи по частям.

3.3. Дайджест Операция

Получив заголовок «Authorization«, сервер может проверить его действительность путем поиска пароля, который соответствует представленному имени пользователя. Затем сервер должен выполнить ту же самую операцию дайджеста (например, MD5), которую выполняет клиент, и сравнить результат с заданным значением дайджеста запроса (request-digest).

Обратите внимание, что серверу HTTP на самом деле не нужно знать пароль пользователя в открытом виде. Пока H (A1) доступен для сервера, действительность заголовка авторизации может быть проверена.

Ответ клиента на запрос «WWW-Authenticate» для пространства защиты начинает сеанс аутентификации с этим пространством защиты (protection space). Сеанс аутентификации продолжается до тех пор, пока клиент не получит еще один запрос «WWW-Authenticate» от любого сервера в области защиты. Клиент должен помнить имя пользователя (username), пароль (password), одноразовый номер (nonce), число одноразовых номеров (nonce count) и непрозрачные значения (opaque values), связанные с сеансом аутентификации, чтобы использовать его для создания заголовка Authorization в будущих запросах в этом пространстве защиты. Заголовок Authorization может быть включен в приоритетном порядке; это повышает эффективность работы сервера и позволяет избежать дополнительных циклов проверки подлинности. Сервер может принять решение принять старую информацию заголовка Authorization, даже если включенное значение «nonce» может быть не новым. В качестве альтернативы сервер может возвратить ответ 401 с новым значением «nonce», заставляя клиента повторить запрос; указав в этом ответе (stale=TRUE), сервер сообщает клиенту повторить попытку с новым одноразовым номером, но без запроса нового имени пользователя и пароля.

Поскольку от клиента требуется возвращать значение непрозрачной директивы, данной ему сервером в течение сеанса, непрозрачные данные могут использоваться для передачи информации о состоянии сеанса аутентификации. (Обратите внимание, что любое такое использование также может быть выполнено более легко и безопасно путем включения состояния в одноразовый номер.) Например, сервер может отвечать за проверку подлинности содержимого, которое фактически находится на другом сервере. Этого удалось бы добиться, если бы первый ответ 401 включал в себя директиву домена, значение которой включает URI на втором сервере, и непрозрачную директиву, значение которой содержит информацию о состоянии. Клиент повторяет запрос, после чего сервер может ответить перенаправлением 301/302, указывая на URI на втором сервере. Клиент будет следовать перенаправлению и передавать заголовок Authorization, включая данные <opaque>.

Как и в случае базовой схемы (basic scheme), прокси-серверы должны быть полностью прозрачными в дайджес схеме аутентификации доступа. То есть они должны пересылать заголовки WWW-Authenticate, Authentication-Info и Authorization без изменений. Если прокси-сервер хочет аутентифицировать клиента до того, как запрос будет перенаправлен на сервер, это можно сделать с помощью заголовков Proxy-Authenticate и Proxy-Authorization, описанных в разделе 3.6 ниже.

 

3.4. Согласование протокола безопасности

Для сервера полезно знать, какие схемы безопасности способен обрабатывать клиент.

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

3.5. Пример

В следующем примере предполагается, что защищенный от доступа документ запрашивается с сервера с помощью запроса GET. URI документа — «http://www.nowhere.org/dir/index.html». И клиент, и сервер знают, что имя пользователя для этого документа — «Mufasa», а пароль — «Circle Of Life» (с одним пробелом между каждым из трех слов).

Когда клиент запрашивает документ в первый раз, заголовок авторизации не отправляется, поэтому сервер отвечает:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
realm="testrealm@host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"

Клиент может запросить у пользователя имя пользователя и пароль, после чего он ответит новым запросом, включая следующий заголовок авторизации:

Authorization: Digest username="Mufasa",
realm="testrealm@host.com",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
qop=auth,
nc=00000001,
cnonce="0a4f113b",
response="6629fae49393a05397450978507c4ef1",
opaque="5ccc069c403ebaf9f0171e9517f40e41"

3.6. Прокси-аутентификация и прокси-авторизация

Схема дайджест-аутентификации может также использоваться для аутентификации пользователей на прокси-серверах, прокси-серверах на прокси-серверах или прокси-серверах на исходных серверах с использованием заголовков «Proxy-Authenticate» и «Proxy-Authorization«. Эти заголовки являются экземплярами заголовков Proxy-Authenticate и Proxy-Authorization, указанных в разделах 10.33 и 10.34 спецификации HTTP/1.1 [2], и их поведение подчиняется описанным там ограничениям. Транзакции для аутентификации через прокси очень похожи на те, что уже описаны. После получения запроса, который требует аутентификации, прокси / сервер должен выдать ответ «407 Proxy Authentication Required» с заголовком «Proxy-Authenticate». Дайджест-вызов (digest-challenge), используемый в заголовке Proxy-Authenticate, такой же, как и для заголовка WWWAuthenticate, как определено выше в разделе 3.2.1.

Клиент/прокси-сервер должен затем повторно выполнить запрос с заголовком Proxy-Authorization, с указаниями, указанными для заголовка Authorization в разделе 3.2.2 выше.

При последующих ответах сервер отправляет Proxy-Authentication-Info с такими же директивами, что и для поля заголовка Authentication-Info.

Обратите внимание, что в принципе клиента можно было бы попросить аутентифицировать себя как для прокси, так и для конечного сервера, но никогда в одном ответе.

4. Соображения безопасности

4.1. Аутентификация клиентов с использованием базовой аутентификации

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

Самым серьезным недостатком обычной аутентификации является то, что она приводит к передаче по существу открытого текста пароля пользователя по физической сети. Именно эту проблему пытается решить дайджест-аутентификация.

Поскольку обычная проверка подлинности включает передачу паролей в виде открытого текста, она НЕ ДОЛЖНА использоваться (без улучшений) для защиты конфиденциальной или ценной информации.

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

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

Базовая аутентификация также уязвима для подделки поддельными серверами. Если можно заставить пользователя поверить, что он подключается к хосту, содержащему информацию, защищенную обычной аутентификацией, когда фактически он подключается к враждебному серверу или шлюзу, то злоумышленник может запросить пароль, сохранить его для дальнейшего использования, и симулировать ошибку. Этот тип атаки невозможен при дайджест-аутентификации. Разработчикам серверов СЛЕДУЕТ защищать от возможности такого подделывания шлюзами или CGI-скриптами. В частности, для сервера очень опасно просто перевернуть соединение со шлюзом. Этот шлюз может затем использовать механизм постоянного соединения для участия в нескольких транзакциях с клиентом, одновременно выдавая себя за исходный сервер способом, который клиент не может обнаружить.

4.2. Аутентификация клиентов с использованием дайджест-аутентификации

Дайджест-аутентификация не обеспечивает надежного механизма аутентификации, например, по сравнению с механизмами на основе открытого ключа. Однако он значительно сильнее, чем (например) CRAM-MD5, который был предложен для использования с LDAP [10], POP и IMAP (см. RFC 2195 [9]). Он призван заменить гораздо более слабый и еще более опасный базовый механизм.

Digest Authentication не обеспечивает никакой защиты конфиденциальности, кроме защиты действительного пароля. Все остальные запросы и ответы доступны перехватчику.

Дайджест-аутентификация обеспечивает только ограниченную защиту целостности сообщений в любом направлении. Если используется механизм «qop=auth-int», то те части сообщения, которые использовались при расчете значений директивы ответа в поле заголовка WWWAuthenticate и Authorization (см. Раздел 3.2 выше), защищены. Большинство полей заголовка и их значения могут быть изменены как часть атаки «человек посередине». (man-in-the-middle)

Дайджест-аутентификация не может удовлетворить многие потребности в безопасных HTTP-транзакциях. Для этих нужд TLS или SHTTP (наверное, опечатка в оригинальном документе) являются более подходящими протоколами. В частности, дайджест-аутентификация не может быть использована для любой транзакции, требующей защиты конфиденциальности. Тем не менее, остается много функций, для которых дайджест-аутентификация полезна и уместна. Любой сервис в настоящее время, который использует Basic, должен быть переключен на Digest как можно скорее.

4.3. Ограниченные использование значений Nonce

Digest схема использует одноразовый номер (nonce), указанный сервером, чтобы инициировать генерацию значения дайджеста запроса (как указано в разделе 3.2.2.1 выше). Как показано в примере одноразового номера в разделе 3.2.1, сервер может создать одноразовый номер таким образом, чтобы его можно было использовать только от конкретного клиента, для конкретного ресурса, в течение ограниченного периода времени или количества использований или любого другого ограничения. Это усиливает защиту, например, от атак воспроизведения (replay attacks) (см. 4.5). Однако следует отметить, что метод, выбранный для генерации и проверки одноразового номера, также влияет на производительность и ресурсы. Например, сервер может разрешить использование каждого одноразового значения только один раз, ведя запись о том, был ли возвращен каждый недавно выданный одноразовый номер и отправляя директиву «next-nonce» в поле заголовка «Authentication-Info» каждого ответа. Это защищает даже от немедленной атаки воспроизведения, но имеет высокую стоимость проверки одноразовых значений и, возможно, более важно, приведет к сбоям аутентификации для любых конвейерных запросов (предположительно, возвращая устаревший индикатор одноразовых номеров). Аналогичным образом, включение специфичного для запроса элемента, такого как значение Etag для ресурса, ограничивает использование одноразового номера этой версией ресурса, а также предотвращает конвейерную обработку. Таким образом, это может быть полезно для методов с побочными эффектами, но неприемлемо для тех, которые этого не делают.

4.4. Сравнение дайджеста с базовой аутентификацией

И дайджест, и базовая аутентификация находятся на слабом конце спектра безопасности. Но сравнение между этими двумя пунктами указывает на полезность и даже необходимость замены Basic на Digest.

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

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

4.5. Повторные атаки

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

Таким образом, для некоторых целей необходимо защитить от повторных атак. Хорошая реализация дайджеста может сделать это различными способами. Созданное сервером значение «nonce» зависит от реализации, но если оно содержит дайджест IP-адреса клиента, метку времени, ETag ресурса и частный ключ сервера (private server key) (как рекомендовано выше), то атака воспроизведения не является простой. Злоумышленник должен убедить сервер в том, что запрос поступает с ложного IP-адреса, и заставить сервер доставить документ на IP-адрес, отличный от адреса, на который, по его мнению, он отправляет документ. Атака может быть успешной только в период до истечения времени. Переваривание IP-адреса клиента и метки времени в одноразовом номере позволяет реализовать реализацию, которая не поддерживает состояние между транзакциями.

Для приложений, в которых нельзя допустить возможность повторной атаки, сервер может использовать одноразовые значения nonce, которые не будут учитываться при повторном использовании. Это требует от сервера дополнительных затрат на запоминание того, какие значения nonce использовались до тех пор, пока не истечет временная метка nonce (и, следовательно, созданный с ее помощью дайджест), но это эффективно защищает от атак воспроизведения.

Реализация должна уделять особое внимание возможности повторных атак с запросами POST и PUT. Если сервер не использует одноразовые или иным образом ограниченные одноразовые номера и / или не настаивает на использовании защиты целостности «qop=auth-int», злоумышленник может воспроизвести действительные учетные данные из успешного запроса с поддельными данными формы или другим телом сообщения. Даже с использованием защиты целостности большинство метаданных в полях заголовка не защищены. Правильное генерирование и проверка одноразовых номеров обеспечивает некоторую защиту от воспроизведения ранее использованных действительных учетных данных, но см. 4.8.

4.6. Слабость, созданная несколькими схемами аутентификации

Сервер HTTP/1.1 может вернуть несколько запросов с ответом 401 (Аутентификация), и каждая задача может использовать свою схему аутентификации. Пользовательский агент ДОЛЖЕН выбрать наиболее строгую схему аутентификации, которую он понимает, и запросить учетные данные у пользователя на основании этой задачи.

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

Когда сервер предлагает выбор схем аутентификации с использованием заголовка WWW-Authenticate, сила результирующей аутентификации будет такой же, как у самой слабой из схем аутентификации. См. Раздел 4.8 ниже для обсуждения конкретных сценариев атак, использующих несколько схем аутентификации.

4.7. Атаки онлайн-словаря

Если злоумышленник может подслушать, он может проверить любые подслушанные пары «nonce/response» против списка общих слов. Такой список обычно намного меньше, чем общее количество возможных паролей. Стоимость вычисления ответа для каждого пароля в списке оплачивается один раз за каждый вызов.

Сервер может смягчить эту атаку, не позволяя пользователям выбирать пароли в словаре.

4.8. Человек посередине

Как базовая, так и дайджест-проверка подлинности уязвимы для атак «человек посередине» (MITM), например, со стороны враждебного или скомпрометированного прокси-сервера. Ясно, что это представляет все проблемы подслушивания. Но это также предлагает некоторые дополнительные возможности для атакующего.

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

Еще лучшая атака MITM состояла бы в том, чтобы удалить все предложенные варианты, заменив их вызовом, который запрашивает только базовую аутентификацию, а затем использует учетные данные открытого текста из базовой аутентификации для аутентификации на исходном сервере с использованием более строгой схемы, которую он запрашивал. Особенно коварный способ организовать такую атаку MITM состоит в том, чтобы предложить «free» (бесплатный) прокси-сервис кеширования доверчивым пользователям.

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

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

4.9. Выбранные атаки открытым текстом

С помощью дайджест-аутентификации MITM или злонамеренный сервер могут произвольно выбирать одноразовый номер (nonce), который клиент будет использовать для вычисления ответа. Это называется атакой «chosen plaintext» (выбранным открытым текстом). Известно, что возможность выбора одноразового номера значительно облегчает криптоанализ (cryptanalysis) [8].

Однако в настоящее время нет способа проанализировать одностороннюю функцию MD5, используемую дайджестом, с использованием выбранного открытого текста.

Противодействие этой атаке заключается в том, что клиенты должны быть сконфигурированы так, чтобы требовать использования необязательной директивы «cnonce«; это позволяет клиенту изменять входные данные для хэша способом, не выбранным злоумышленником.

4.10. Атаки по предварительно вычисленным словарям

С помощью дайджест-аутентификации, если злоумышленник может выполнить выбранную атаку открытым текстом, злоумышленник может предварительно вычислить ответ для многих общих слов на одноразовый номер по своему выбору и сохранить словарь пар (ответ, пароль). Такое предварительное вычисление часто может выполняться параллельно на многих машинах. Затем он может использовать выбранную атаку с открытым текстом, чтобы получить ответ, соответствующий этой проблеме, и просто найти пароль в словаре. Даже если большинство паролей отсутствует в словаре, некоторые могут быть. Поскольку злоумышленник выбирает задачу, стоимость вычисления ответа для каждого пароля в списке может быть амортизирована из-за нахождения многих паролей. Словарь со 100 миллионами пар пароль/ответ займет около 3,2 гигабайта дискового пространства.

Противодействие этой атаке заключается в том, чтобы клиенты были настроены так, чтобы требовать использования необязательной директивы «cnonce».

4.11. Групповые атаки методом грубой силы

С помощью дайджест-аутентификации MITM может выполнять выбранную атаку с открытым текстом и может собирать ответы от многих пользователей на один и тот же одноразовый номер. Затем он может найти все пароли в любом подмножестве пространства паролей, которое сгенерирует одну из пар «nonce/response» за один проход по этому пространству. Это также сокращает время нахождения первого пароля на коэффициент, равный количеству собранных пар «nonce/response«. Такой поиск пространства паролей часто можно выполнять параллельно на многих машинах, и даже одна машина может очень быстро искать большие подмножества пространства паролей — существуют отчеты о поиске всех паролей с шестью или менее буквами в течение нескольких часов.

Противодействие этой атаке заключается в том, чтобы клиенты были настроены так, чтобы требовать использования необязательной директивы «cnonce».

4.12. Подмена поддельных серверов

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

4.13. Хранение паролей

Дайджест-аутентификация требует, чтобы агент аутентификации (обычно сервер) сохранял некоторые данные, полученные из имени пользователя и пароля, в «файле паролей», связанном с данной областью. Обычно это может содержать пары, состоящие из имени пользователя и H (A1), где H (A1) — это усвоенное значение имени пользователя, области и пароля, как описано выше.

Для безопасности это означает, что если этот файл паролей будет взломан, злоумышленник получит немедленный доступ к документам на сервере, используя эту область. В отличие от, скажем, стандартного файла паролей UNIX, эту информацию не нужно расшифровывать, чтобы получить доступ к документам в области сервера, связанной с этим файлом. С другой стороны, для получения пароля пользователя потребуется расшифровка или, что более вероятно, атака методом перебора. Это причина того, что область является частью переваренных данных, хранящихся в файле паролей. Это означает, что если один файл пароля аутентификации Digest скомпрометирован, он автоматически не скомпрометирует других с тем же именем пользователя и паролем (хотя он подвергает их атаке методом грубой силы «brute force»).

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

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

4.14. Резюме

По современным криптографическим стандартам дайджест-аутентификация слаба. Но для широкого спектра целей он полезен в качестве замены базовой аутентификации. Это исправляет некоторые, но не все, недостатки базовой аутентификации. Его сила может варьироваться в зависимости от реализации. В частности, структура одноразового номера (которая зависит от реализации сервера) может повлиять на простоту установки атаки воспроизведения. Целый ряд серверных опций является подходящим, поскольку, например, некоторые реализации могут быть готовы принять серверные накладные расходы одноразовых «nonce» или дайджестов, чтобы исключить возможность воспроизведения. Другие могут быть удовлетворены одноразовым номером, подобным рекомендованному выше, ограниченным одним IP-адресом и одним ETag или ограниченным временем жизни.

Суть в том, что * любая * совместимая реализация будет относительно слабой по криптографическим стандартам, но * любая * совместимая реализация будет намного превосходить базовую аутентификацию.

 

5. Пример реализации

Следующий код реализует вычисления H (A1), H (A2), запроса-дайджеста и ответа-дайджеста, а также тестовую программу, которая вычисляет значения, использованные в примере из раздела 3.5. Он использует реализацию MD5 из RFC 1321.

Файл «digcalc.h»:

#define HASHLEN 16
typedef char HASH[HASHLEN];
#define HASHHEXLEN 32
typedef char HASHHEX[HASHHEXLEN+1];
#define IN
#define OUT

/* calculate H(A1) as per HTTP Digest spec */
void DigestCalcHA1(
IN char * pszAlg,
IN char * pszUserName,
IN char * pszRealm,
IN char * pszPassword,
IN char * pszNonce,
IN char * pszCNonce,
OUT HASHHEX SessionKey
);

/* calculate request-digest/response-digest as per HTTP Digest spec */
void DigestCalcResponse(
IN HASHHEX HA1, /* H(A1) */
IN char * pszNonce, /* nonce from server */
IN char * pszNonceCount, /* 8 hex digits */
IN char * pszCNonce, /* client nonce */
IN char * pszQop, /* qop-value: "", "auth", "auth-int" */
IN char * pszMethod, /* method from the request */
IN char * pszDigestUri, /* requested URL */
IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
OUT HASHHEX Response /* request-digest or response-digest */
);

Файл «digcalc.c»:

#include <global.h>
#include <md5.h>

#include <string.h>
#include "digcalc.h"

void CvtHex(
IN HASH Bin,
OUT HASHHEX Hex
)
{
unsigned short i;
unsigned char j;
for (i = 0; i < HASHLEN; i++) {
j = (Bin[i] >> 4) & 0xf;
if (j <= 9)
Hex[i*2] = (j + ’0’);
else
Hex[i*2] = (j + ’a’ - 10);
j = Bin[i] & 0xf;
if (j <= 9)
Hex[i*2+1] = (j + ’0’);
else
Hex[i*2+1] = (j + ’a’ - 10);
};
Hex[HASHHEXLEN] = ’\0’;
};

/* calculate H(A1) as per spec */

void DigestCalcHA1(
IN char * pszAlg,
IN char * pszUserName,
IN char * pszRealm,
IN char * pszPassword,
IN char * pszNonce,
IN char * pszCNonce,
OUT HASHHEX SessionKey
)
{
MD5_CTX Md5Ctx;
HASH HA1;
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, pszUserName, strlen(pszUserName));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszRealm, strlen(pszRealm));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszPassword, strlen(pszPassword));
MD5Final(HA1, &Md5Ctx);
if (stricmp(pszAlg, "md5-sess") == 0) {
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, HA1, HASHLEN);
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
MD5Final(HA1, &Md5Ctx);
};
CvtHex(HA1, SessionKey);
};

/* calculate request-digest/response-digest as per HTTP Digest spec */

void DigestCalcResponse(
IN HASHHEX HA1, /* H(A1) */
IN char * pszNonce, /* nonce from server */
IN char * pszNonceCount, /* 8 hex digits */
IN char * pszCNonce, /* client nonce */
IN char * pszQop, /* qop-value: "", "auth", "auth-int" */
IN char * pszMethod, /* method from the request */
IN char * pszDigestUri, /* requested URL */
IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */
OUT HASHHEX Response /* request-digest or response-digest */
)
{
MD5_CTX Md5Ctx;
HASH HA2;
HASH RespHash;
HASHHEX HA2Hex;
// calculate H(A2)
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, pszMethod, strlen(pszMethod));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszDigestUri, strlen(pszDigestUri));
if (stricmp(pszQop, "auth-int") == 0) {
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
};
MD5Final(HA2, &Md5Ctx);
CvtHex(HA2, HA2Hex);
// calculate response
MD5Init(&Md5Ctx);
MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszNonce, strlen(pszNonce));
MD5Update(&Md5Ctx, ":", 1);
if (*pszQop) {
MD5Update(&Md5Ctx, pszNonceCount, strlen(pszNonceCount));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszCNonce, strlen(pszCNonce));
MD5Update(&Md5Ctx, ":", 1);
MD5Update(&Md5Ctx, pszQop, strlen(pszQop));
MD5Update(&Md5Ctx, ":", 1);
};
MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
MD5Final(RespHash, &Md5Ctx);
CvtHex(RespHash, Response);
};

File «digtest.c»:

#include <stdio.h>
#include "digcalc.h"
void main(int argc, char ** argv) {
char * pszNonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
char * pszCNonce = "0a4f113b";
char * pszUser = "Mufasa";
char * pszRealm = "testrealm@host.com";
char * pszPass = "Circle Of Life";
char * pszAlg = "md5";
char szNonceCount[9] = "00000001";
char * pszMethod = "GET";
char * pszQop = "auth";
char * pszURI = "/dir/index.html";
HASHHEX HA1;
HASHHEX HA2 = "";
HASHHEX Response;
DigestCalcHA1(pszAlg, pszUser, pszRealm, pszPass, pszNonce,
pszCNonce, HA1);
DigestCalcResponse(HA1, pszNonce, szNonceCount, pszCNonce, pszQop,
pszMethod, pszURI, HA2, Response);
printf("Response = %s\n", Response);
};

6. Благодарности

Эрик У. Синк (Eric W. Sink) из AbiSource, Inc., был одним из авторов, прежде чем спецификация претерпела существенные изменения.

В дополнение к авторам ценную дискуссию, способствующую созданию этого документа, пришли Питер Дж. Черчард (Peter J. Churchyard), Нед Фрид (Ned Freed) и Дэвид М. Кристол (David M. Kristol).

Джим Геттис (Jim Gettys) и Ларри Масинтер (Larry Masinter) редактировали этот документ для обновления.

7. Ссылки

[1] Berners-Lee, T., Fielding, R. and H. Frystyk, «Hypertext Transfer Protocol — HTTP/1.0», RFC 1945, May 1996.

[2] Fielding, R., Gettys, J., Mogul, J., Frysyk, H., Masinter, L., Leach, P. and T. Berners-Lee, «Hypertext Transfer Protocol — HTTP/1.1», RFC 2616, June 1999.

[3] Rivest, R., «The MD5 Message-Digest Algorithm», RFC 1321, April 1992.

[4] Freed, N. and N. Borenstein. «Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies», RFC 2045, November 1996.

[5] Dierks, T. and C. Allen «The TLS Protocol, Version 1.0», RFC 2246, January 1999.

[6] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P., Luotonen, A., Sink, E. and L. Stewart, «An Extension to HTTP : Digest Access Authentication», RFC 2069, January 1997.

[7] Berners Lee, T, Fielding, R. and L. Masinter, «Uniform Resource Identifiers (URI): Generic Syntax», RFC 2396, August 1998.

[8] Kaliski, B.,Robshaw, M., «Message Authentication with MD5», CryptoBytes, Sping 1995, RSA Inc, (http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm)

[9] Klensin, J., Catoe, R. and P. Krumviede, «IMAP/POP AUTHorize Extension for Simple Challenge/Response», RFC 2195, September 1997.

[10] Morgan, B., Alvestrand, H., Hodges, J., Wahl, M., «Authentication Methods for LDAP», Work in Progress.

8. Авторы и адреса

John Franks
Professor of Mathematics
Department of Mathematics
Northwestern University
Evanston, IL 60208-2730, USA
EMail: john@math.nwu.edu

Phillip M. Hallam-Baker
Principal Consultant
Verisign Inc.
301 Edgewater Place
Suite 210
Wakefield MA 01880, USA
EMail: pbaker@verisign.com

Jeffery L. Hostetler
Software Craftsman
AbiSource, Inc.
6 Dunlap Court
Savoy, IL 61874
EMail: jeff@AbiSource.com

Scott D. Lawrence
Agranat Systems, Inc.
5 Clocktower Place, Suite 400
Maynard, MA 01754, USA
EMail: lawrence@agranat.com

Paul J. Leach
Microsoft Corporation
1 Microsoft Way
Redmond, WA 98052, USA
EMail: paulle@microsoft.com

Ari Luotonen
Member of Technical Staff
Netscape Communications Corporation
501 East Middlefield Road
Mountain View, CA 94043, USA

Lawrence C. Stewart
Open Market, Inc.
215 First Street
Cambridge, MA 02142, USA
EMail: stewart@OpenMarket.com
Franks,

Copyright (C) Интернет-общество (1999). Все права защищены.

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

Ограниченные разрешения, предоставленные выше, являются бессрочными и не будут отменены Обществом Интернета или его правопреемниками или правопреемниками.
Этот документ и информация, содержащаяся в настоящем документе, предоставляются на условиях «КАК ЕСТЬ», и ИНТЕРНЕТ-ОБЩЕСТВО И ИНТЕРНЕТ-ИНЖЕНЕРНАЯ ЗАДАЧА ОТКАЗЫВАЕТСЯ ОТ ВСЕХ ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО ОГРАНИЧИВАЕТСЯ НИКАКИХ ГАРАНТИЙ, ЧТО ИСПОЛЬЗОВАНИЕ ИНФОРМАЦИИ ЗДЕСЬ НЕ БУДЕТ НАРУШИТЬ ЛЮБЫЕ ПРАВА ИЛИ ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ ТОВАРНОГО ОБЕСПЕЧЕНИЯ ИЛИ ПРИГОДНОСТИ ДЛЯ ОСОБЫХ ЦЕЛЕЙ.

Подтверждение

Финансирование функции RFC Editor в настоящее время обеспечивается Обществом Интернета.