RFC2617表示将用户名和密码编码为base64,但没有说明在创建用于输入base64算法的八位字节时要使用的字符编码。
我应该假设US-ASCII还是UTF8?或者有人已经在某个地方解决了这个问题?
答案 0 :(得分:56)
RFC 2617可以读作“ISO-8859-1”或“undefined”。你的选择。众所周知,许多服务器使用ISO-8859-1(喜欢或不喜欢),并且在发送其他内容时会失败。所以可能唯一安全的选择就是坚持使用ASCII。
有关更多信息和解决问题的建议,请参阅草案"An Encoding Parameter for HTTP Basic Authentication"(构成RFC 7617的基础)。
自2015年以来,有RFC 7617,它废弃了RFC 2617.与旧的RFC相比,新的RFC明确定义了用于用户名和密码的字符编码。
charset="UTF-8"
,如下所示:WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
完整版:
阅读the spec。如果包含其他详细信息,例如确切的编码过程以及应支持的Unicode代码点列表。
自2018年起,如果用户输入用户名或密码的非ASCII字符(即使服务器不使用charset
参数),现代浏览器通常会默认为UTF-8。
即使在RFC 7617中,领域参数仍然只支持ASCII字符。
答案 1 :(得分:36)
简答:iso-8859-1,除非按照RFC2047(MIME)使用编码字。
更长的解释:
RFC2617, section 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
对于BNF中的定义(如上所述),如果不参考RFC2616(HTTP 1.1),则不应阅读规范:
此规范是HTTP / 1.1规范2的配套产品。 它使用该文档的增强BNF部分2.1,并依赖于 该文件中定义的非终端和其他方面 HTTP / 1.1规范。
RFC2616, section 2.1定义 TEXT (强调我的):
TEXT规则仅用于描述性字段内容和值 不打算由消息解析器解释。话 * TEXT可以包含除字符集以外的字符 ISO-8859-1 仅在根据RFC 2047的规则进行编码时。
TEXT = <any OCTET except CTLs, but including LWS>
除非你根据RFC2047(MIME pt.3)规则检测到其他编码,否则它绝对是iso-8859-1:
// Username: Mike
// Password T€ST
Mike:=?iso-8859-15?q?T€ST?=
在这种情况下,根据iso-8859-15,单词中的欧元符号将被编码为0xA4
。我的理解是你应该检查这些编码的单词分隔符,然后根据指定的编码解码里面的单词。如果不这样做,您会认为密码为=?iso-8859-15?q?T¤ST?=
(请注意,0xA4
在解释为iso-8859-1时会被解码为¤
。
这是我的理解,我找不到比这些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中最重要的一点)。
编辑:我刚刚意识到这个答案从服务器端的角度来看更多的问题。
答案 2 :(得分:4)
如果您对在登录提示符下输入非ascii字符时浏览器的操作感兴趣,我只是尝试使用Firefox。
通过获取每个unicode值的最低有效字节,似乎懒惰地将everithing转换为ISO-8859-1,例如:
User: 豚 (\u8c5a)
Password: 虎 (\u864e)
编码与:
相同User: Z (\u005a)
Password: N (\u004e)
0x5a 0x3a 0x4e base64-&gt; WjpO
答案 3 :(得分:4)
除了RFC,在 Spring框架中,BasicAuthenticationFilter
类,默认为 UTF-8 。
我认为这个选择的原因是UTF-8能够编码所有可能的字符,而ISO-8859-1(或ASCII)则不能。尝试使用系统不支持的字符的用户名/密码可能会导致行为中断或(可能更糟)安全性降低。