http摘要认证
摘要认证的握手过程
1, 第一次客户端请求的时候,服务器产生一个随机数nonce,服务器将这个随机数放在WWW-Authenticate响应头,与服务器支持的认证算法列表,认证的域realm一起发送给客户端,如下例子:
HTTP /1.1 401 Unauthorized
WWW-Authenticate:Digest
realm= ”test realm”
qop=auth,auth-int”
nonce=”66C4EF58DA7CB956BD04233FBB64E0A4”
2, 客户端发现是401响应,表示需要进行认证,则弹出让用户输入用户名和密码的认证窗口,客户端选择一个算法,计算出密码和其他数据的摘要,将摘要放到Authorization的请求头中发送给服务器,如果客户端要对服务器也进行认证,这个时候,可以发送客户端随机数cnonce。如下例子:
GET/cgi-bin/checkout?a=b HTTP/1.1
Authorization: Digest
username=”tenfyguo”
realm=”test realm”
nonce=” 66C4EF58DA7CB956BD04233FBB64E0A4” //服务器端的随机数一起带回
uri=”/cgi-bin/checkout?a=b” //必须跟请求行一致
qop=”auth” //保护质量参数
nc=0000001
cnonce=”xxxxx234132543strwerr65sgdrftdfytryts” //客户端随机数,用于对称校验
response=” ABC4EF58DA7CB956BD04345FBB64E0A4”//最终摘要
3, 服务接受摘要,选择算法以及掌握的数据,重新计算新的摘要跟客户端传输的摘要进行比较,验证是否匹配,若客户端反过来用客户端随机数对服务器进行质询,就会创建客户端摘要,服务可以预先将下一个随机数计算出来,提前传递给客户端,通过Authentication-Info发送下一个随机数。如下例子:
HTTP/1.1 200 OK
Authorization-Info:nextnonce=” 88C4EF58DA7CB956BD04233FBB64E0A4”
qop=”auth”
rspauth=”23543534DfasetwerwgDTerGDTERERRE”
cnonce=” xxxxx234132543strwerr65sgdrftdfytryts”
四,摘要的计算
在说明如何计算摘要之前,先说明参加摘要计算的信息块。信息块主要有两种:
1,表示与安全相关的数据的A1。
A1中的数据时密码和受保护信息的产物,它包括用户名,密码,保护域和随机数等内容,A1只涉及安全信息,与底层报文自身无关。
若算法是:MD5
则A1=<user>:<realm>:<password>
若算法是:MD5-sess
则A1=MD5(<user>:<realm>:<password>):<nonce>:<cnonce>
2,表示与报文相关的数据的A2.
A2表示是与报文自身相关的信息,比如URL,请求反复和报文实体的主体部分,A2加入摘要计算主要目的是有助于防止反复,资源或者报文被篡改。
若qop未定义或者auth:
A2=<request-method>:<uri-directive-value>
若qop为auth:-int
A2=<request-method>:<uri-directive-value>:MD5(<request-entity-body>)
下面定义摘要的计算规则:
若qop没有定义:
摘要response=MD5(MD5(A1):<nonce>:MD5(A2))
若qop为auth:
摘要response=MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
若qop为auth-int:
摘要response= MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
五,随机数的生成
RFC2617建议采用这个假想的随机数公式:
nonce = BASE64(time-stamp MD5(time-stamp “:” ETag “:” private-key))
其中:
time-stamp是服务器产生的时间戳或者其他不会重复的序列号,ETag是与所请求实体有关的HTTP ETag首部的值,priviate-key是只有服务器知道的数据。
这样,服务器就可以收到客户端的认证首部之后重新计算散列部分,如果结果与那个首部的随机数不符,或者是时间戳的值不够新,就可以拒绝请求,服务器可以通过这种方式来限制随机数的有效持续时间。
包括了ETag可以防止对已经更新资源版本的重放请求。注意:在随机数中包含客户端IP,服务器好像就可以限制原来获取此随机数的客户端重用这个随机数了,但这会破坏代理集群的工作,使用代理集群时候,来自单个用户的多条请求通常会经过不同的代理进行传输,而且IP地址欺骗实现起来也不复杂。