- 基本认证是最流行的 HTTP 认证协议。几乎每个主要的客户端和服务器都实现了基本认证机制。
- 基本认证最初是在 HTTP/1.0 规范中提出的,但此后被移到了 RFC 2617 中,它详细介绍了 HTTP 的认证机制。
1. 基本认证流程
- 在基本认证中:
- 用户发出请求,请求服务器上某个安全域中的文件。
- 服务器会返回 401 状态码来初始化认证质询,并回送 WWW-Authenticate 响应首部,要求对安全域进行基本认证。
- 浏览器收到 401 质询时,会打开一个对话框,请求用户输入这个域的用户名和密码。用户输入用户名和密码时,浏览器会用一个冒号将其连接起来,编码成“经过扰码的” Base-64 表示形式,再将其放在 Authorization 请求首部回送给服务器。
- 服务器对用户名和密码进行解码,验证它们的正确性,然后用一条 HTTP 200 OK 报文返回所请求的报文。注意,基本认证协议并没有 Authentication-Info 首部。
- 基本认证的首部:
- 质询(服务器发往客户端)
网站的不同部分可能有不同的密码。域就是一个引用字符串,用来命名所请求的文档集,这样用户就知道该使用哪个密码了:
WWW-Authenticate: Basic realm="安全域名称"
- 响应(客户端发往服务器)
用冒号(:)将用户名和密码连接起来,然后转换成 Base-64 编码,这样在用户名和密码中包含国际字符会稍微容易一些,也能尽量避免通过观察网络流量并只进行一些粗略的检查就可以获取用户名和密码情况的发生:
Authorization: Basic base64编码的用户名:密码
- 质询(服务器发往客户端)
2. Base-64 用户名/密码编码
- HTTP 将 Base-64 编码用于基本认证及摘要认证,在几种 HTTP 扩展中也使用了该编码。
- 基本认证中用户名/密码转换如下所示:
- Base-64 编码原理如下:
1. Base-64 编码保证了二进制数据的安全
- Base-64 编码可以将任意一组字节转换成较长的常见文本字符序列,从而可以合法地作为首部字段值。Base-64 编码将用户输入或二进制数据,打包成一种安全格式,将其作为 HTTP 首部字段的值发送出去,而无须担心其中包含会破坏 HTTP 分析程序的冒号、换行符或二进制值。
- Base-64 编码是作为 MIME 多媒体电子邮件标准的一部分开发的,这样 MIME 就可以在不同的合法电子邮件网关之间传输富文本和任意的二进制数据了。
- Base-64 编码与将二进制数据文本化表示的 uuencode 和 BinHex 标准在本质上很类似,但空间效率更高。MIME RFC 2045 的第 6.8 节详细介绍了 Base-64 算法。
2. 8位到6位
- Base-64 编码将一个 8 位字节序列拆散为 6 位的片段,并为每个 6 位的片段分配一个字符,这个字符是 Base-64 字母表中的 64 个字符之一。
- 这 64 个输出字符都是很常见的,可以安全地放在 HTTP 首部字段中。这 64 个字符中包含大小写字母、数 字、+ 和 /,还使用了特殊字符 =。
- 注意,由于 Base-64 编码用了 8 位字符来表示信息中的 6 个位,所以 Base-64 编码字符串大约比原始值扩大了 33%。
- Base-64字母表:
- 下图为简单的 Base-64 编码实例:
- 字符串“Ow!”被拆分成 3 个 8 位的字节(0x4F、0x77、0x21)。
- 这 3 个字节构成了一个 24 位的二进制值 010011110111011100100001。
- 这些位被划分为一些 6 位的序列 010011、110111、01110、100001。
- 每个 6 位值都表示了从 0 ~ 63 之间的一个数字,对应 Base-64 字母表中 64 个字符之一。得到的 Base-64 编码字符串是个 4 字符的字符串“T3ch”,然后就可以通过线路将这个字符串作为“安全的”8 位字符传送出去,因为只用了一些移植性最好的字符(字母、数字等)。
3. Base-64 填充
- Base-64 编码收到一个 8 位字节序列,将这个二进制序列流划分成 6 位的块。二进制序列有时不能正好平均地分成 6 位的块,在这种情况下,就在序列末尾填充 0 位,使二进制序列的长度成为 24 的倍数(6 和 8 的最小公倍数)。
- 对已填充的二进制串进行编码时,任何完全填充(不包含原始数据中的位)的 6 位组都由特殊的第 65 个符号“=”表示。如果 6 位组是部分填充的,就将填充位设置为 0。
- 填充实例:
输入数据 | 二进制序列(填充位以x表示) | 已编码数据 |
---|---|---|
a:a | 011000 010011 101001 100001 | YTph |
a:aa | 011000 010011 101001 100001 011000 01xxxx xxxxxx xxxxxx | YTphYQ== |
a:aaa | 011000 010011 101001 100001 011000 010110 0001xx xxxxxx | YTphYWE= |
a:aaaa | 011000 010011 101001 100001 011000 010110 000101 100001 | YTphYWFh |
4. Perl实现
- MIME::Base64 是 Perl 中的 Base-64 编/解码模块。可以在 http://www.perldoc.com/perl5.6.1/lib/MIME/Base64.html 上看到有关这个模块的内容。
- 可以用 MIME::Base64 encode_base64 和 decode_base64 方法对字符串进行编解码:
use MIME::Base64;
$encoded = encode_base64('Aladdin:open sesame');
$decoded = decode_base64($encoded);
3. 代理认证
- 中间的代理服务器也可以实现认证功能。有些组织会在用户访问服务器、LAN 或无线网络之前,用代理服务器对其进行认证。可以在代理服务器上对访问策略进行集中管理,因此,通过代理服务器提供对某组织内部资源的统一访问控制是一种很便捷的方式。这个过程的第一步就是通过代理认证(proxy authentication)来识别身份。
- 代理认证的步骤与 Web 服务器身份验证的步骤相同。但首部和状态码都有所不同。
- Web服务器与代理认证首部和状态码的差异:
Web服务器 | 代理服务器 |
---|---|
Unauthorized status code: 401 | Unauthorized status code: 407 |
WWW-Authenticate | Proxy-Authenticate |
Authorization | Proxy-Authorization |
Authentication-Info | Proxy-Authentication-Info |