为什么Base64在基本认证中

时间:2012-12-01 16:39:09

标签: http header basic-authentication

为什么生成的字符串文字“username:password”在Authorization标头中用Base64编码?它的背景是什么?

2 个答案:

答案 0 :(得分:6)

要理解以下内容,您应该清楚地了解the differences between "character set" and "character encoding"

此外,请注意Base64编码encoding is not encryption。在Base64中编码的任何内容都很容易解码。

Base64编码,最重要的是,确保用户:传递字符都是ASCII字符集和ASCII编码的一部分。用户:传入HTTP Basic auth是Authorization header-field值的一部分。 HTTP标头值是ASCII(或扩展ASCII)编码/解码。因此,当您对Base64编码用户:pass时,确保它是ASCII,因此是一个有效的标头字段值。

Base64编码还为明文用户:pass添加了至少某些类混淆。同样,这是加密。但是,它确实阻止了普通人阅读用户:一目了然。从安全角度来看,这似乎几乎没有意义,我只是因为以下背景信息而包含它。

一些背景

如果查看RFC 2616(现已过时)和RFC 2617,您会看到他们定义了标题字段值基本身份验证用户:分别传递为TEXT;即,ISO-8859-1 OCTECT(ISO-8859-1是8位扩展ASCII编码)。这很奇怪,因为它使看起来像一样,作者希望兼容的用户:pass应该使用与HTTP头所​​需的相同的字符集/编码,在这种情况下,Base64编码似乎毫无意义除了琐碎的混淆。

也就是说,很难相信这些RFC的作者没有想到用户名/密码是非ASCII(非ISO-8859-1)字符集。假设他们有非ASCII用户:记住,他们可能一直担心如何在所有ASCII标头集的中间包含/维护/传输非ASCII字节。 Base64编码用户:pass肯定很好地解决了这个问题。还有使用Base64的更典型的原因 - to make data transmission more reliable。我的理解是HTTP是8-bit clean;即使标题以ASCII格式发送,我也不认为user:pass的Base64编码是为了使其传输更可靠。

在不问原作者的情况下,我不确定我们是否确实知道。 Here's an interesting comment on the topic by Julian Reschke。他是RFC 5987, Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters的作者。他还在HTTP RFC上做了大量工作,包括最新的HTTP 1.1 RFC大修。

当前HTTP 1.1 RFC处理HTTP头编码RFC 7230,现在建议使用USASCII(也称为ASCII,7位ASCII)作为标头。 RFC 5987定义了一个标头参数编码规范 - 可能有些人正在使用它。 RFC 7235是最近对RFC 2617进行HTTP身份验证的更新。

答案 1 :(得分:4)

这是编码之前的production rule for the userid-password元组:

userid-password   = [ token ] ":" *TEXT

此处token指定如下:

   token          = 1*<any CHAR except CTLs or tspecials>

这基本上是any US-ASCII character,范围在32到126之间,但没有some special characters()<>@,;:\"/[,{{ 1}},]?={,空格和水平制表符。)

TEXT指定如下:

}

这基本上是除octet(代码点0-31,127)但control characters序列之外的任何including linear whitespace(0-255)序列,它是一个或多个空格或水平制表符可能在CRLF序列之前:

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

虽然这不会破坏标题字段值LWS has the same semantics as a single space

  

全部线性      空格,包括折叠,具有与SP相同的语义。

为了保持这样的序列,字符串在被放置为字段值之前进行编码。