HTTP Authentication
身份认证、身份验证
HTTP 提供了多种身份认证方案,它们通过 challenge–response(质询响应)让服务器在提供所请求的内容之前识别并发出质询。
Basic Access Authentication,基本访问认证(验证)
Digest Access Authentication,摘要访问认证(验证)
一. 通用框架
HTTP 为访问控制和身份认证提供了一个通用框架,通过一组可扩展的 challenge–response 身份认证方案。使用此方案,服务器可以 challenge 客户端请求,客户端可以提供 authentication 信息。
服务器在收到 unauthenticated(未经身份认证)的 request 后,如果希望浏览器向其认证自身身份,那么服务器返回的 response 必须包含以下两部分:
HTTP 401 Unauthorized
的状态行WWW-Authenticate
header
当浏览器要向服务器发送 authentication credential(身份认证凭证)时,使用
Authorization
header。
HTTP 401 Unauthorized
WWW-Authenticate: <method> x=x, y=y, ...
Authorization: <method> xxx
单词 authenticate,证明...是真实的、证实,prove sth is real or true
单词 authorization,批准、授权,official permission
所以是:
server 要求 client 证明自己的身份
client 提供自己的身份信息,请求 server 授权
HTTP Authentication 规范还允许服务器在根 URI 下定义单独的 authentication scope,即 Authentication Realm(认证领域)。
二. 基本访问认证
基本访问认证是对 web 资源进行访问控制的一种最简单的技术,因为它不需要 cookie、session ID 以及登录页面,而是使用的 HTTP header 中的标准字段。HTTP 基本认证最初是在 1993 年实现的,1996 年在 HTTP 1.0 规范中定义,2015 年在 RFC 7617 中指定。
基本访问认证提供了一种在 HTTP request 中设置用户名和密码的方法。
在 HTTP 基本认证中,request 中包含一个 Authorization
header 字段,形如:
其中 <credentials>
的值是 username:password
的 Base64 编码。
WWW-Authenticate
WWW-Authenticate
Authorization
Authorization
Authorization
header 的值,构造步骤如下:
用户名和密码用
:
分隔。这意味着用户名本身不能包含:
将字符串编码为八位位组序列。默认情况,只要它和 US-ASCII 兼容就行。服务器也可以通过
charset
参数指定建议的编码方式(是在 Response 的WWW-Authenticate
header 中)用 Base64 进行编码
将 authorization method(如
Basic
)和一个空格字符(即Basic
)拼接在最前面
使用说明
为了保证机密性,HTTP 基本认证通常会和 HTTPS 配合使用,毕竟它只用了 Base64 编码
通常需要浏览器缓存凭据(credential)一段合理的时间,以避免不断提示用户输入用户名和密码,毕竟它要求每个 HTTP 请求的 header 中必须提供
Authorization
字段。而浏览器之间的缓存策略可能会不相同HTTP 不提供 web 服务器指示客户端退出登录的方法。但是,有多种方法可以清除某些 web 浏览器中缓存的凭据。其中之一是故意让凭据不正确,从而把用户重定向到同域中的 URL。然而,这种行为在不同的浏览器和浏览器版本之间是不一致的。比如 Microsoft IE 提供了专用的 JavaScript 方法来清除缓存的凭据
document.execCommand('ClearAuthenticationCache')
在现代浏览器中,用于基本认证的缓存凭据,通常会在清除浏览历史记录时被清除。大多数浏览器允许用户单独清除凭据,尽管那个选项可能很难找,并且通常会清除所有访问过的站点的凭据
浏览器不会主动检测和阻止暴力破解凭据,除非使用服务器端机制
补充:
还有一种被称为 Bearer 认证的方式,它将一个 token 存放在
Authorization
header 中用于身份认证,这个 token 可以是一个简单的随机串,也可以是一个包含更多信息的 JWT(JSON Web Token)字符串,这依赖于 server 的使用方式。在用户登录成功之后,server 端根据用户名和密码生成 token,并将其返回给前端,前端将 token 存储在 session storage 中。对于要进行身份认证的 API,前端在发送 HTTP request 之前,取出 token 并按规则拼好,即
<authorization method> + 空格 + token
,将值赋给Authorization
header。此时的身份认证相关的信息都在 server 端维护,包括加密、缓存时间。前端要做的就是处理好相应的 response code,即当返回
HTTP 401 Unauthorized
时,跳转登录页面。
三. 摘要访问认证
摘要访问认证是 web 服务器和浏览器协商 credential(凭据,比如用户名、密码)的方法之一,用于在发送敏感信息之前确认用户身份。该机制会对用户名和密码应用哈希函数,在通过网络发送它们之前。
从技术上讲,摘要认证是 MD5 cryptographic hashing(MD5 加密哈希)的一个应用,同时使用 nonce(随机数)值来防止重放攻击(replay attack)。摘要认证使用 HTTP 协议。
在 cryptography(密码学)中,nonce(随机数)是在密码通信中只能使用一次的任意数字。
nonce 通常是在认证协议中发出的随机数或伪随机数,以确保旧通信不能在重放攻击中重复使用。
nonce 还可以用作初始化向量和加密哈希函数。
安全性
在 RFC 2617 中,安全性 = MD5 Hash + 可选的增强功能
MD5 Hash
哈希函数、加密算法
server 和 client 都会用到
qop
quality of protection,保护质量
server 提供
nonce
随机数
server 和 client 会各自生成自己的
nonce counter
随机数计数器
client 提供(依次递增)
2015 年 9 月,RFC 7616 取代了 RFC 2617,添加了 4 个新算法:SHA-256
, SHA-256-sess
, SHA-512-256
和 SHA-512-256-sess
。该编码相当于 MD5
和 MD5-sess
算法,只是将 MD5 hash 函数替换成了 SHA-256 和 SHA-512-256 函数。只是浏览器对新算法的支持还不太好。
关于 MD5 安全性对摘要认证的影响,简要介绍如下:
HTTP 摘要认证中使用的 MD5 计算旨在单向,这意味着当仅知道输出时,应该很难确定原始输入。但如果密码本身太简单,那么可以测试所有可能的输入并找到匹配的输出(暴力攻击),也许可以借助字典或合适的查找列表,这对 MD5 来说可是很容易可行的。
HTTP 方案是由 Phillip Hallam-Baker 在 CERN 于 1993 年设计的,并没有纳入认证系统的后续改进,比如 HMAC(keyed-hash message authentication code,密钥哈希消息认证代码)的开发。
加密结构是基于 MD5 散列函数,到目前为止,MD5 冲突攻击尚未被证明对摘要式认证构成威胁,RFC 2617 允许服务器实现检测某些冲突和重放攻击的机制。
WWW-Authenticate
WWW-Authenticate
参数说明:
authentication
realm
:通常是对正在访问的计算机或系统的描述nonce
:response 随机数,是随机生成的一次性值qop
:quality of protection,保护质量
Authorization
Authorization
提供了用户名和密码之后,客户端会重新发送相同的请求,并会把 response 里包含的 authentication headers 都加上。
新参数的说明:
username
:uri
:nc
:nonce counter,客户端递增的随机数计数器cnonce
:client nonce,nonceresponse
:其值是根据指定的 algorithm 和 qop,利用加密函数MD5()
算出来的由于服务器和客户端具有相同的信息,因此可以通过执行相同的计算来检查 response
举个例子:其中 MD5()
表示一个用来计算 MD5 hash 的函数,\
表示换行连续。
此时,客户端可能会发出另一个 request,重用服务器的 nonce(随机数)值(服务器只会为每个 401
response 发新的 nonce),同时提供新的客户端随机数(cnonce)。对于后续请求,十六进制 request counter(nc,请求计数器)必须大于其使用的最后一个值,否则攻击者就可以简单地使用相同的 credentials 重放旧 request。服务器负责确保 counter(计数器)针对其发出的每个 nonce 值而递增,从而适当地拒绝任何错误请求。显然,更改 method、URI 或 counter 的值都将导致不同的 response value。
服务器应该记住它最近生成的 nonce 值。它还可以记住每个 nonce 值的发布时间,并在一定时间后使其过期失效。如果使用过期值,服务器应使用 401
状态代码进行响应,同时添加 stale=TRUE
到 authentication header,以指示客户端应使用提供的新 nonce 重新发送,而不是提示用户输入另一个用户名和密码。
服务器不需要保留任何过期的 nonce 值,它可以简单地假设任何无法识别的值都是已经过期的。服务器也可以允许每个 nonce 只能返回一次,尽管这会迫使客户端重复每个请求。请注意,让服务器 nonce 立即过期是行不通的,因为客户端永远没有机会使用它。
其它:
在 server 端,.htdigest
文件用来存储摘要认证的 username、realm 和 password。
在 client 端,有些浏览器不支持某些功能,比如 auth-int checking, MD5-sess algorithm。如果服务器要求处理这些可选功能,客户端可能无法进行身份认证。
还有些软件已经弃用摘要认证了,因为它(与基本认证 over HTTPS 相比)的一些缺点,比如软件 Bitbucket、Symfony PHP framework。
使用说明
优点
HTTP 摘要认证的一些安全优势,包括:
密码未明确发送到服务器
密码不直接在摘要中使用,而是在
HA1 = MD5(username:realm:password)
中,这允许某些实现存储 HA1 而不是明文密码RFC 2617 中引入了客户端随机数,允许客户端防止明文攻击
服务器随机数允许包含时间戳,因此服务器可以检查客户端提交的 nonce 属性,以防止重放攻击
服务器还可以维护最近发布或使用的服务器 nonce 值的列表,以防止重复使用
可以防止网络钓鱼(把真正的请求发到恶意服务器),因为 plain 密码永远不会发送到任何服务器,无论服务器是否正确(公钥系统依赖于用户能认证 URL 是否正确)
缺点
HTTP 摘要认证的几个缺点:
网站无法控制最终向用户呈现的界面
RFC 2617 中的许多安全选项都是可选的。如果服务器未指定保护质量(qop),则客户端将以安全性更低的旧版 RFC 2069 模式运行
摘要访问认证容易受到 MITM(中间人)攻击。例如,MITM 攻击者可以告诉客户端使用基本访问认证或传统 RFC2069 摘要访问认证模式。为了进一步扩展这一点,摘要访问认证不为客户端提供认证服务器身份的机制
服务器可以存储
HA1 = MD5(username:realm:password)
而不是密码本身。然而,如果存储的 HA1 被泄露,攻击者可以生成有效的响应并访问域中的文档,就像访问密码本身一样容易。因此,存 HA1 值的表必须像包含明文密码的文件一样受到安全保护摘要访问认证阻止在存储密码时使用强密码哈希(比如 bcrypt),因为密码或摘要用户名、领域和密码必须是可恢复的
此外,由于 FIPS 中不允许使用 MD5 算法,因此 HTTP 摘要认证将无法与 FIPS 认证的加密模块一起使用
替代身份认证协议
到目前为止,最常见的方法是使用 HTTP+HTML form-based authentication(基于 HTTP+HTML 表单的身份认证)明文协议,或更罕见的方法是使用基本访问认证。 这些弱明文协议与 HTTPS 网络加密一起使用,可以解决摘要访问认证旨在防止的许多威胁。 然而,HTTPS 的这种使用依赖于终端用户能准确地认证他们每次访问的 URL 是正确的,以防止将其密码发送到不受信任的服务器,从而导致网络钓鱼攻击。 可惜的是,用户经常无法做到这一点,这就是为什么网络钓鱼已成为最常见的安全漏洞形式。
一些偶尔使用的基于 Web 的应用程序的强认证协议包括:
使用客户端证书进行公钥认证,通常通过 HTTPS/SSL 客户端证书实现
Kerberos 或 SPNEGO 认证,比如由 Microsoft IIS 使用(运行配置为集成 Windows 认证)
安全远程密码协议,最好在 HTTPS/TLS 层内
JSON Web Token 是基于 JSON 的标准 RFC 7519,用于创建断言一定数量声明的访问令牌
主要参考
RFC 2617: HTTP Authentication: Basic and Digest Access Authentication
Last updated