为什么在基本身份验证中使用Base64



为什么username:password的结果字符串文字在Authorization标头中使用Base64编码?它的背景是什么?

要理解以下内容,您应该清楚地了解"字符集";以及";字符编码";。

此外,请记住Base64是编码,并且编码是而不是加密。Base64中编码的任何内容都很容易解码。

最重要的是,Base64编码确保了用户:传递字符都是ASCII字符集的一部分,并且是ASCII编码的。HTTP基本身份验证中的user:pass是Authorization头字段值的一部分。HTTP标头值是ASCII(或扩展ASCII)编码/解码的。因此,当您对user:pass进行Base64编码时,您可以确保它是ASCII,因此是一个有效的头字段值。

Base64编码还为明文user:pass添加了至少某种类型的模糊处理。同样,这是而不是加密。但是,它确实阻止了正常人阅读用户:一目了然。从安全角度来看,这似乎毫无意义,我之所以将其包括在内,是因为以下背景信息。

一些背景

如果你看一下RFC 2616(现在已经过时)和RFC 2617,你会发现它们分别将头字段值Basic auth-user:pass定义为TEXT;即ISO-8859-1 OCECTs(ISO-8859-1是8位扩展ASCII编码)。这很奇怪,因为它让看起来就像作者想要的那样,兼容的user:pass应该使用与HTTP标头所需的相同的字符集/编码,在这种情况下,除了琐碎的模糊处理之外,Base64编码似乎毫无意义。

也就是说,很难相信那些RFC的作者没有想到用户名/密码是非ASCII(非ISO-8859-1)字符集。假设他们脑海中有非ASCII用户:通行证,他们可能会关心如何在一组全ASCII报头的中间包含/维护/传输非ASCII字节。对user:pass进行Base64编码当然很好地解决了这个问题。使用Base64还有一个更规范的原因——使数据传输更可靠。我的理解是HTTP是8位干净的;尽管头文件是以ASCII形式发送的,但我不认为user:pass的Base64编码是为了使其传输更加可靠。

如果不询问原始作者,我不确定我们是否会确定。下面是朱利安·雷什克对这个话题的一个有趣的评论。他是RFC 5987,超文本传输协议(HTTP)头字段参数的字符集和语言编码的作者。他还做了很多关于HTTP RFC的工作,包括最新的HTTP 1.1 RFC大修。

目前处理HTTP标头编码的HTTP 1.1 RFC,RFC 7230,现在建议使用USASCII(又名ASCII,7位ASCII)作为标头。RFC 5987定义了一个头部参数编码规范——可能有些人正在使用它。RFC 7235是关于HTTP身份验证的RFC 2617的最新更新。

这是userid password元组编码前的生成规则:

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

此处令牌指定如下:

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

这基本上是32到126范围内的任何US-ASCII字符,但没有一些特殊字符(()<>@,;:"/[]?={}、空格和水平制表符)。

TEXT指定如下:

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

这基本上是任何八位字节(0–255)序列,除了控制字符(代码点0–31127),但包括线性空白序列,线性空白序列是一个或多个空格或水平制表符,前面可能有CRLF序列:

LWS            = [CRLF] 1*( SP | HT )

虽然这不会破坏头字段值,但LWS具有与单个空格相同的语义:

所有线性空白,包括折叠,具有与SP相同的语义。

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

最新更新