Какую кодировку следует использовать для обычной проверки подлинности HTTP?



RFC2617 говорит, что кодирует имя пользователя и пароль для base64, но не говорит, какую кодировку символов использовать при создании октетов для ввода в алгоритм base64.



должен ли я предположить US-ASCII или UTF8? Или кто-то уже где-то решил этот вопрос?

655   4  

4 ответов:

Оригинал spec-RFC 2617

RFC 2617 можно читать как "ISO-8859-1"или " неопределенный". Ваш выбор. Известно, что многие серверы используют ISO-8859-1 (нравится это или нет) и потерпят неудачу, когда вы отправите что-то еще. Поэтому, вероятно, единственный безопасный выбор-придерживаться ASCII.

для получения дополнительной информации и предложения по исправлению ситуации см. Проект "параметр кодировки для обычной аутентификации HTTP" (который лег в основу RFC 7617).

New-RFC 7617

С 2015 года есть RFC 7617, который устаревает RFC 2617. В отличие от старого RFC, новый RFC явно определяет кодировку символов, которая будет использоваться для имени пользователя и пароля.

  • кодировка по умолчанию все еще не определена. Is требуется только для совместимости с US-ASCII (что означает, что он сопоставляет ASCII-байты с ASCII-байтами, как это делает UTF-8).
  • сервер может дополнительно отправить параметр аутентификации charset="UTF-8" в своем вызове, как это:
    WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
    Это объявляет, что сервер будет принимать символы, отличные от ASCII, в имени пользователя / пароле и что он ожидает, что они будут закодированы в UTF-8 (в частности, форма нормализации C). Обратите внимание, что разрешен только UTF-8.

Полная версия:

читать спец. Если содержит дополнительные сведения, такие как точная процедура кодирования и список Кодовые точки Юникода, которые должны поддерживаться.

поддержка браузеров

С 2018 года современные браузеры обычно будут по умолчанию использовать UTF-8, если пользователь вводит символы, отличные от ASCII, для имени пользователя или пароля (даже если сервер не использует

короткий ответ: iso-8859-1, если только кодированные слова не используются в соответствии с RFC2047 (MIME).

более длинное объяснение:

RFC2617, раздел 2 (проверка подлинности http) определяет basic-credentials:

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

спецификация не должна быть прочитана без ссылки на RFC2616 (HTTP 1.1) для определения в BNF (например, выше):

эта спецификация является приложением к спецификации HTTP/1.1 2. Он использует дополненный раздел 2.1 BNF этого документа и полагается на как нетерминалы, определенные в этом документе, так и другие аспекты спецификация HTTP / 1.1.

адресу rfc2616, секции 2.1 определяет текст (выделено мной):

текстовое правило используется только для описания содержимого и значений полей которые не предназначены для интерпретации анализатором сообщений. Слова из * текст может содержат символы из наборов символов, отличных от ISO-8859-1 только при кодировании в соответствии с правилами RFC 2047.

TEXT           = <any OCTET except CTLs, but including LWS>

так что это определенно iso-8859-1, Если вы не обнаружите какую-то другую кодировку в соответствии с RFC2047 (MIME pt. 3) правила:

// Username: Mike
// Password T€ST
Mike:=?iso-8859-15?q?T€ST?=

в этом случае знак евро в слове будет закодирован как 0xA4 по данным iso-8859-15. Это мое понимание, что вы должны проверить их кодируются разделители слов, а затем декодируются слова внутри на основе указанной кодировки. Если вы этого не сделаете, вы будете думать, что пароль =?iso-8859-15?q?T¤ST?= (извещение 0xA4 будет расшифрован ¤ при интерпретации как iso-8859-1).

это мое понимание, я не могу найти более явного подтверждения, чем эти RFC. И некоторые из них кажутся противоречивыми. Например, одна из 4 заявленных целей RFC2047 (MIME, pt. 3) чтобы переопределить:

формат сообщения чтобы учесть ... текстовая информация заголовка в наборы символов, отличные от US-ASCII.

но затем RFC2616 (HTTP 1.1) определяет заголовок, используя текстовое правило, которое по умолчанию имеет значение iso-8859-1. Означает ли это, что каждое слово в этом заголовке должно быть закодированным словом (т. е. =?...?= форма)?

также актуально, ни один текущий браузер не делает этого. Они используют utf-8 (Chrome, Opera), iso-8859-1 (Safari), системную кодовую страницу (IE) или что-то еще (например, только самое значительное бит из utf-8 в случае Firefox).

Edit:я только что понял, что этот ответ смотрит на проблему больше с точки зрения сервера.

Если вас интересует, что делают браузеры, когда вы вводите символы, отличные от ascii, в приглашении на вход, я просто попробовал с Firefox.

Кажется, что он лениво преобразует everithing в ISO-8859-1, беря наименее значимый байт каждого значения unicode, например:

User: 豚 (\u8c5a)
Password: 虎 (\u864e)

кодируются так же, как:

User: Z (\u005a)
Password: N (\u004e)

0x5a 0x3a 0x4e base64 - > WjpO

RFC в сторону, в Spring framework на BasicAuthenticationFilter класс, по умолчанию UTF-8.

причина этого выбора я считаю, что UTF-8 способен кодировать все возможные символы, в то время как ISO-8859-1 (или ASCII) - нет. Попытка использовать имя пользователя / пароль с символами, не поддерживаемыми в системе, может привести к нарушению поведения или (возможно, хуже) ухудшению безопасности.

Comments

    Ничего не найдено.