我应该使用什么编码进行HTTP基本身份验证?

Dob*_*eer 73 http basic-authentication

RFC2617表示将用户名和密码编码为base64,但没有说明在创建用于输入base64算法的八位字节时要使用的字符编码.

我应该假设US-ASCII或UTF8吗?或者有人已经在某处解决了这个问题?

Jul*_*hke 59

原始规范 - RFC 2617

RFC 2617可以读作"ISO-8859-1"或"未定义".你的选择.众所周知,许多服务器使用ISO-8859-1(喜欢或不喜欢),并且在发送其他内容时会失败.所以可能唯一安全的选择就是坚持使用ASCII.

有关更多信息和修复此情况的建议,请参阅草案"HTTP基本身份验证的编码参数"(它构成了RFC 7617的基础).

新的 - RFC 7617

自2015年以来,RFC 7617废弃了RFC 2617.与旧RFC相比,新RFC明确定义了用于用户名和密码的字符编码.

  • 默认编码仍未定义.只需要与US-ASCII兼容(意味着它将ASCII字节映射到ASCII字节,就像UTF-8一样).
  • 服务器可以可选地发送附加的验证参数charset="UTF-8"在它的挑战,例如:
    WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
    此宣布,服务器将接受在用户名/密码的非ASCII字符,并且,它预计它们在UTF-8(具体范式C)要被编码.请注意,只允许使用UTF-8.

完整版:

阅读规范.如果包含其他详细信息,例如确切的编码过程以及应支持的Unicode代码点列表.

浏览器支持

截至2018年,如果用户输入用户名或密码的非ASCII字符(即使服务器不使用该charset参数),现代浏览器通常默认为UTF-8 .

领域

即使在RFC 7617中,realm参数仍然只支持ASCII字符.


Mic*_*out 39

简答:iso-8859-1,除非按照RFC2047(MIME)使用编码字.

更长的解释:

RFC2617,第2节(HTTP身份验证)定义了基本凭据:

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
Run Code Online (Sandbox Code Playgroud)

对于BNF中的定义(如上所述),如果不参考RFC2616(HTTP 1.1),则不应读取规范:

此规范是HTTP/1.1规范2的配套.它使用该文档的增强BNF部分2.1,并依赖于该文档中定义的非终端和HTTP/1.1规范的其他方面.

RFC2616,第2.1节定义了TEXT(强调我的):

TEXT规则仅用于描述性字段内容和不打算由消息解析器解释的值.*TEXT的字只有在根据RFC 2047的规则编码时才包含ISO-8859-1以外的字符集中的字符 .

TEXT           = <any OCTET except CTLs, but including LWS>
Run Code Online (Sandbox Code Playgroud)

所以它绝对是iso-8859-1,除非您根据RFC2047(MIME pt.3)规则检测到其他编码:

// Username: Mike
// Password T€ST
Mike:=?iso-8859-15?q?T€ST?=
Run Code Online (Sandbox Code Playgroud)

在这种情况下,单词中的欧元符号将0xA4根据iso-8859-15进行编码.我的理解是你应该检查这些编码的单词分隔符,然后根据指定的编码解码里面的单词.如果不这样做,您会认为密码是=?iso-8859-15?q?T¤ST?=(当解释为iso-8859-1时0xA4将被解码的通知¤).

这是我的理解,我找不到比这些RFC更明确的确认.其中一些似乎是矛盾的.例如,RFC2047(MIME,第3页)的4个既定目标之一是重新定义:

允许... US-ASCII以外的字符集中的文本标题信息的消息格式.

但是RFC2616(HTTP 1.1)使用TEXT规则定义了一个标头,默认为iso-8859-1.这是否意味着此标题中的每个单词都应该是一个编码字(即=?...?=表单)?

同样相关,目前没有浏览器这样做.他们使用utf-8(Chrome,Opera),iso-8859-1(Safari),系统代码页(IE)或其他东西(就像Firefox中的utf-8中最重要的一点).

编辑:我刚刚意识到这个答案从服务器端的角度来看更多的问题.

  • HTTPbis规范将不再提及RFC 2047. (4认同)

hol*_*s83 5

除了 RFC,在Spring 框架中BasicAuthenticationFilter类,默认是UTF-8

我认为这个选择的原因是 UTF-8 能够编码所有可能的字符,而 ISO-8859-1(或 ASCII)则不能。尝试使用带有系统不支持的字符的用户名/密码可能会导致破坏行为或(可能更糟)降低安全性。