【问题标题】:Why Base64 in Basic Authentication为什么在基本身份验证中使用 Base64
【发布时间】:2012-11-19 15:04:26
【问题描述】:

为什么“用户名:密码”的结果字符串文字在授权标头中使用 Base64 编码?它的背景是什么?

【问题讨论】:

标签: http header basic-authentication


【解决方案1】:

要理解以下内容,你应该对the differences between "character set" and "character encoding"有一个清晰的认识。

另外,请记住Base64 是一个编码,而encoding is not encryption。以 Base64 编码的任何内容都有意易于解码。

Base64 编码,最重要的是,确保 user:pass 字符都是ASCII 字符集的一部分,并且是 ASCII 编码的。 HTTP Basic auth 中的 user:pass 是 Authorization 标头字段值的一部分。 HTTP 标头值是 ASCII(或扩展 ASCII)编码/解码的。因此,当您对 user:pass 进行 Base64 编码时,请确保它是 ASCII,因此是有效的标头字段值。

Base64 编码还为明文 user:pass 添加了至少 一些 类型的混淆。同样,这不是加密。但是,它确实会阻止普通人一目了然地阅读 user:pass。从安全角度来看,这似乎几乎毫无意义,我之所以将其包括在内,是因为以下背景信息。

一些背景

如果您查看RFC 2616(现已过时)和RFC 2617,您会发现它们分别定义了标头字段值 Basic auth user:pass,如文本;即 ISO-8859-1 OCTECT(ISO-8859-1 是 8 位扩展 ASCII 编码)。这很奇怪,因为它 似乎 就像作者希望兼容的 user:pass 应该使用与 HTTP 标头所需的字符集/编码相同的字符集/编码,在这种情况下,Base64 编码似乎毫无意义除了琐碎的混淆。

也就是说,很难相信那些 RFC 的作者没有想到用户名/密码是非 ASCII(非 ISO-8859-1)字符集。假设他们有非 ASCII user:passes,他们可能会担心如何在所有 ASCII 标头集的中间包含/维护/传输非 ASCII 字节。 Base64 编码 user: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 是关于 HTTP 身份验证的 RFC 2617 的最新更新。

【讨论】:

    【解决方案2】:

    这是编码前的 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()&lt;&gt;@,;:\"/[]?={}、空格和水平制表符)。 >

    TEXT指定如下:

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

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

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

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

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

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

    【讨论】:

    • 好点,但是 : 登录用户名或密码是什么意思?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 2014-09-15
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2019-01-28
    相关资源
    最近更新 更多