Digest認證是爲了修復基本認證協議的嚴重缺陷而設計的,秉承「毫不經過明文在網絡發送密碼」的原則,經過「密碼摘要」進行認證,大大提升了安全性。html
相對於基本認證,主要有以下改進:算法
須要注意的是,摘要認證除了可以保護密碼以外,並不能保護其餘內容,與HTTPS配合使用還是一個良好的選擇。如下是摘要認證的具體流程圖:瀏覽器
看到上面出現了那麼多以前沒見過的參數,是否是有點慌(或是興奮)?彆着急,這裏先給出一個概覽:安全
WWW-Authentication
:用來定義使用何種方式(Basic、Digest、Bearer等)去進行認證以獲取受保護的資源realm
:表示Web服務器中受保護文檔的安全域(好比公司財務信息域和公司員工信息域),用來指示須要哪一個域的用戶名和密碼qop
:保護質量,包含auth
(默認的)和auth-int
(增長了報文完整性檢測)兩種策略,(能夠爲空,可是)不推薦爲空值nonce
:服務端向客戶端發送質詢時附帶的一個隨機數,這個數會常常發生變化。客戶端計算密碼摘要時將其附加上去,使得屢次生成同一用戶的密碼摘要各不相同,用來防止重放攻擊nc
:nonce計數器,是一個16進制的數值,表示同一nonce下客戶端發送出請求的數量。例如,在響應的第一個請求中,客戶端將發送「nc=00000001」。這個指示值的目的是讓服務器保持這個計數器的一個副本,以便檢測重複的請求cnonce
:客戶端隨機數,這是一個不透明的字符串值,由客戶端提供,而且客戶端和服務器都會使用,以免用明文文本。這使得雙方均可以查驗對方的身份,並對消息的完整性提供一些保護response
:這是由用戶代理軟件計算出的一個字符串,以證實用戶知道口令Authorization-Info
:用於返回一些與受權會話相關的附加信息nextnonce
:下一個服務端隨機數,使客戶端能夠預先發送正確的摘要rspauth
:響應摘要,用於客戶端對服務端進行認證stale
:當密碼摘要使用的隨機數過時時,服務器能夠返回一個附帶有新隨機數的401響應,並指定stale=true
,表示服務器在告知客戶端用新的隨機數來重試,而再也不要求用戶從新輸入用戶名和密碼了1.當打開須要認證的頁面時,會彈出一個對話框,要求用戶輸入用戶名和密碼服務器
2.使用Fidder監聽請求,能夠看到在未進行認證或認證失敗的狀況下,服務端會返回401 Unauthorized
給客戶端,並附帶Challenge網絡
3.輸入正確的用戶名和密碼後,瀏覽器會生成密碼摘要以及其餘信息發送給服務端,服務端認證成功後,返回一些與受權會話相關的附加信息,放在Authorization-Info
中。性能
其中,客戶端選擇的保護質量策略爲auth
,response
就是經過計算獲得的密碼摘要,具體計算方式以下(使用默認的MD5加密算法):
MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
加密
算法 | A1 |
---|---|
MD5(默認) | <username>:<realm>:<password> |
MD5-sess | MD5(<username>:<realm>:<password>):<nonce>:<cnonce> |
qop | A2 |
---|---|
auth(默認) | <request-method>:<uri> |
auth-int | <request-method>:<uri>:MD5(<request-entity-body>) |
另外,rspauth
使得客戶端能夠對服務器進行認證,稱爲響應摘要。響應摘要的計算與請求摘要相似,但因爲響應中沒有方法,並且報文實體數據有所不一樣,全部只有報文主題信息A2不一樣。具體區別以下:spa
qop | A2 |
---|---|
auth(默認) | :<uri> |
auth-int | :<uri>:MD5(<response-entity-body>) |
4.當服務端隨機數過時時,再次請求認證,能夠看到質詢中增長了stale=true
,用戶無需再次輸入用戶名和密碼,瀏覽器會自動使用新的質詢參數進行密碼摘要的計算。設計
1.預受權:服務端預先告知客戶端下一個隨機數是多少,使得客戶端能夠直接生成正確的Authorization
首部,避免了屢次「請求/質詢」。經常使用的有一下三種方式:
Authorization-Info
成功首部中發送下一個隨機數nextnonce
。雖然這種機制加快了事務處理的速度,可是它也破壞了對同一臺服務器的屢次請求進行管道化的功能,可能會形成很大的損失。stale=true
。雖然這確實下降了安全性,可是重用的隨機數的生存週期是可控的,應該在安全和性能之間找到平衡。2.RFC 2617建議採用這個假想的隨機數公式:
BASE64(timestamp MD5(timestamp ":" ETag ":" private-key))
其中,timestamp
是服務器產生隨機數的時間或其餘不重複的值,ETag
是與所請求實體有關的HTTP ETag首部的值,private-key
是隻有服務器知道的私鑰。