導航
一、概述
Digest認證是為了修復基本認證協議的嚴重缺陷而設計的,秉承“絕不通過明文在網路傳送密碼”的原則,通過“密碼摘要”進行認證,大大提高了安全性。
相對於基本認證,主要有如下改進:
- 絕不通過明文在網路上傳送密碼
- 可以有效防止惡意使用者進行重放攻擊
- 可以有選擇的防止對報文內容的篡改
需要注意的是,摘要認證除了能夠保護密碼之外,並不能保護其他內容,與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不同。具體區別如下:
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
是隻有伺服器知道的私鑰。