RFC2617表示将用户名和密码编码为base64,但没有说明在创建八位字节输入base64算法时使用哪种字符编码。
我应该采用US-ASCII还是UTF8?还是有人已经在某个地方解决了这个问题?
Answers:
RFC 2617可以读取为“ ISO-8859-1”或“未定义”。你的选择。众所周知,许多服务器都使用ISO-8859-1(无论是否喜欢),并且在发送其他内容时会失败。因此,可能唯一安全的选择是坚持使用ASCII。
有关更多信息和解决此问题的建议,请参阅“ HTTP基本身份验证的编码参数”草稿(构成RFC 7617的基础)。
自2015年以来,存在RFC 7617,它取代了RFC2617。与旧RFC相比,新RFC明确定义了用于用户名和密码的字符编码。
charset="UTF-8"
在其质询中发送一个附加的身份验证参数,如下所示:WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
完整版本:
阅读规范。如果包含其他详细信息,例如确切的编码过程以及应支持的Unicode代码点列表。
从2018年开始,如果用户输入用户名或密码的非ASCII字符(即使服务器未使用该charset
参数),现代浏览器通常将默认为UTF-8 。
即使在RFC 7617中,领域参数仍仅支持ASCII字符。
简短的答案: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
如果不参考RFC2616(HTTP 1.1)中的BNF定义(如上述内容),则不应阅读该规范:
该规范是HTTP / 1.1规范2的伴随。它使用了该文档的增强BNF第2.1节,并依赖于该文档中定义的非终端以及HTTP / 1.1规范的其他方面。
RFC2616第2.1节定义了TEXT(强调我的):
TEXT规则仅用于描述性字段内容和消息解析器不打算解释的值。仅当按照RFC 2047的规则进行编码时,* TEXT的单词才可以包含ISO-8859-1以外的字符集的字符 。
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?=
(注意,当解释为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的最高有效位)。
编辑:我刚刚意识到这个答案更多地从服务器端的角度看问题。
除了RFC,在Spring框架中,BasicAuthenticationFilter
该类的默认值为UTF-8。
我相信选择该标记的原因是UTF-8能够编码所有可能的字符,而ISO-8859-1(或ASCII)则不能。尝试将用户名/密码与系统中不支持的字符一起使用会导致行为中断或(可能更糟)降低安全性。
如果您对在登录提示符下输入非ASCII字符时浏览器的功能感兴趣,我就尝试使用Firefox。
通过采用每个unicode值的最低有效字节,似乎将所有内容延迟转换为ISO-8859-1,例如:
User: 豚 (\u8c5a)
Password: 虎 (\u864e)
编码与:
User: Z (\u005a)
Password: N (\u004e)
0x5a 0x3a 0x4e base64-> WjpO