1. 程式人生 > >HTTP - 摘要認證

HTTP - 摘要認證

分享 版本 首部 列表 gpo nbsp 三方 tps bubuko

基本認證便捷靈活,但極不安全。用戶名和密碼都是以明文形式傳送的,也沒有采取任何措施防止對報文的篡改。安全使用基本認證的唯一方式就是將其與 SSL 配合使用。

摘要認證是另一種 HTTP 認證協議,它與基本認證兼容,但卻更為安全。摘要認證試圖修復基本認證協議的嚴重缺陷。具體來說,摘要認證進行了如下改下:

  • 永遠不會以明文方式在網絡上發送密碼。
  • 可以防止惡意用戶捕獲並重放認證的握手過程。
  • 可以有選擇地防止對報文內容的篡改。
  • 防範其他幾種常見的攻擊方式。

摘要認證並不是最安全的協議。摘要認證並不能滿足安全 HTTP 事務的很多需求。對這些需求來說,使用 TLS 和 HTTPS 協議更為合適一些。但摘要認證比它要取代的基本認證強大很多。

摘要認證的工作原理

下面來看看摘要認證的工作原理(簡化版本):

技術分享圖片

a) 客戶端請求了某個受保護文檔。

b) 在客戶端能夠證明其知道密碼從而確認其身份之前,服務器拒絕提供文檔。服務器向客戶端發起質詢,詢問用戶名和摘要形式的密碼。

c) 客戶端傳遞了密碼的摘要,證明它是知道密碼的。服務器知道所有用戶的秘密,因此可以將客戶提供的摘要與服務器自己計算得到的摘要進行比較,以驗證用戶是否知道密碼。另一方在不知道密碼的情況下,很難偽造出正確的摘要。

d) 服務器將客戶端提供的摘要與服務器內部計算出的摘要進行對比。如果匹配,就說明客戶端知道密碼(或者很幸運地猜中了!)。可以設置摘要函數,使其產生很多數字,讓人不可能幸運地猜中摘要。服務器進行了匹配驗證之後,會將文檔提供給客戶端——整個過程都沒有在網絡上發送密碼。

重放攻擊

使用摘要就無需以明文形式發送密碼了。可以只發送密碼的摘要,而且可以確信,沒有哪個惡意用戶能輕易地從摘要中解碼出原始密碼。

但是,僅僅隱藏密碼並不能避免危險,因為即便不知道密碼,別有用心的人也可以截獲摘要,並一遍遍地重放給服務器。摘要和密碼一樣好用。

為防止此類重放攻擊的發生,服務器可以向客戶端發送了一個稱為隨機數 (nonce) 的特殊令牌,這個數會經常發生變化(可能是每毫秒,或者是每次認證都變化)。客戶端在計算摘要之前要先將這個隨機數令牌附加到密碼上去。

在密碼中加入隨機數就會使摘要隨著隨機數的每一次變化而變化。記錄下的密碼摘要只對特定的隨機數有效,而沒有密碼的話,攻擊者就無法計算出正確的摘要,這樣就可以防止重放攻擊的發生。

摘要認證要求使用隨機數,因為這個小小的重放弱點會使未隨機化的摘要認證變得和基本認證一樣脆弱。隨機數是在 WWW-Authenticate 質詢中從服務器傳送給客戶端。

摘要認證的握手機制

下面是簡化的摘要認證三步握手機制:

技術分享圖片

(1) 服務器計算出一個隨機數。

(2) 服務器將這個隨機數放在 WWW-Authenticate 質詢報文中,與服務器所支持的算法列表一同發往客戶端。

(3) 客戶端選擇一個算法,計算出密碼和其他數據的摘要。

(4) 客戶端將摘要放在一條 Authorization 報文中發回服務器。如果客戶端要對服務器進行認證,可以發送客戶端隨機數。

(5) 服務器接收摘要、選中的算法以及支撐數據,計算出與客戶端相同的摘要。然後服務器將本地生成的摘要與網絡傳送過來的摘要進行比較,驗證是否匹配。如果客戶端反過來用客戶端隨機數對服務器進行質詢,就會創建客戶端摘要。服務器可以預先將下一個隨機數計算出來,提前將其傳遞給客戶端,這樣下一次客戶端就可以預先發送正確的摘要了。

預授權

普通的認證方式中,事務結束之前,每條請求都要有一次請求/質詢的需要,參見下圖 (a)。

如果客戶端事先知道下一個隨機數是什麽,就可以取消這個請求/質詢循環,這樣客戶端就可以在服務器發出請求之前,生成正確的 Authorization 首部了。如果客戶端能在服務器要求他計算 Authorization 首部之前將其計算出來,就可以預先將 Authorization 首部發送給服務器,而不用進行請求/質詢了。下圖 (b) 顯示了這種方式對性能的影響。

技術分享圖片

預授權對基本認證來說並不重要(而且很常見)。瀏覽器通常會維護一些客戶端數據庫以存儲用戶名和密碼。一旦用戶與某站點進行了認證,瀏覽器通常會為後繼對那個 URL 的請求發送正確的 Authorization 首部。

由於摘要認證使用了隨機數技術來破壞重放攻擊,所以對摘要認證來說,預授權要稍微復雜一些。服務器會產生任意的隨機數,所以在客戶端收到質詢之前,不一定總能判定應該發送什麽樣的 Authorization 首部。

摘要認證在保留了很多安全特性的同時,還提供了集中預授權方式。這裏列出了三種可選的方式,通過這些方式,客戶端無效等待新的 WWW-Authenticate 質詢,就可以獲得正確的隨機數:

  • 服務器預先在 Authentication-Info 成功首部中發送下一個隨機數;
  • 服務器允許在一小段時間內使用同一個隨機數;
  • 客戶端和服務器使用同步的、可預測的隨機數算法。

預先生成下一個隨機數

可以在 Authentication-Info 成功首部中將下一個隨機數預先提供給客戶端。這個首部是與前一次成功認證的 200 OK 響應一同發送的。

Authentication-Info: nextnonce="<nonce-value>"

有了下一個隨機數,客戶端就可以預先發布 Authorization 首部了。

盡管這種預授權機制避免了請求/質詢循環(加快了事務處理的速度),但實際上它也破壞了對同一臺服務器的多條請求進行管道化的功能,因為在發布下一條請求之前,一定要收到下一個隨機值才行。而管道化是避免延遲的一項基本技術。所以這樣可能會造成很大的性能損失。

受限制的隨機數重用機制

另一種方法不是預先生成隨機數序列,而是在有限的次數內重用隨機數。比如,服務器可能允許將某個隨機重用 5 次,或者重用 10 秒。

在這種情況下,客戶端可以隨意發布帶有 Authorization 首部的請求,而且由於隨機數是事先知道的,所以還可以對請求進行管道化。隨機數過期時,服務器要向客戶端發送 401 Unauthorized 質詢,並設置 WWW-Authenticate:stale=true 指令:

WWW-Authenticate: Digest realm="<realm-value>", nonce="<nonce-value>", stale=true

重用隨機數使得攻擊者更容易成功地實行重放攻擊。雖然這確實降低了安全性,但重用的隨機數的生存周期是可控的(從嚴格禁止重用到較長時間的重用),所以應該可以在安全和性能間找到平衡。

同步生成隨機數

還可以采用時間同步的隨機數生成算法,客戶端和服務器可根據共享的密鑰,生成第三方無法輕易預測的、相同的隨機數序列。

HTTP 認證首部

技術分享圖片

HTTP - 摘要認證