HTTP摘要認證
摘要訪問認證是一種協定規定的Web伺服器用來同網頁瀏覽器進行認證資訊協商的方法。它在密碼發出前,先對其應用雜湊函式,這相對於HTTP基本認證傳送明文而言,更安全。
概述
編輯摘要訪問認證最初由 RFC 2069 (HTTP的一個擴充:摘要訪問認證)中被定義。RFC 2069 大致定義了一個傳統的由伺服器生成亂數來維護安全性的摘要認證架構。認證回應由下列組成(HA1、HA2、A1、及A2為字串變數的名稱):
RFC 2069 隨後被 RFC 2617 (HTTP 認證:基本及摘要訪問認證)取代。RFC 2617 引入了一系列安全增強的選項;「保護品質」(qop)、亂數計數器由客戶端增加、以及客戶生成的亂數。這些增強為了防止如選擇明文攻擊的密碼分析。
如果 qop 值為「auth」或未指定,那麼 HA2 為
如果 qop 值為「auth-int」,那麼 HA2 為
如果 qop 值為「auth」或「auth-int」,那麼如下計算 response:
如果 qop 未指定,那麼如下計算 response:
上面所述的這種當 qop 未指定的情況,也就是遵循簡化的 RFC 2069 標準。
MD5 安全問題對摘要認證的影響
編輯在 HTTP 摘要認證中使用 MD5 加密是為了達成"不可逆的",也就是說,當輸出已知的時候,確定原始的輸入應該是相當困難的。如果密碼本身太過簡單,也許可以通過嘗試所有可能的輸入來找到對應的輸出(窮舉攻擊),甚至可以通過字典或者適當的尋找表加快尋找速度。
HTTP 構架由Phillip Hallam-Baker於1993年在CERN設計成的,並且沒有吸收後續認證系統的改進,如基於金鑰的雜湊訊息驗證碼HMAC的發展。雖然所使用的密碼結構是基於MD5雜湊函式的,在2004年,通常認為衝突攻擊不會影響明文(如密碼)未被得知的應用。[1][來源請求] 但是,在2006年的聲明 (Kim, Biryukov2, Preneel, Hong, "On the Security of HMAC and NMAC Based on HAVAL MD4 MD5 SHA-0 and SHA-1") 導致了一些包括關於 MD5 應用的疑慮。不過,至今為止,MD5 衝突攻擊沒有被視為對摘要認證的威脅,並且 RFC 2617 允許伺服器實現一些機制來檢測衝突以及重放攻擊。
HTTP摘要認證的考慮
編輯優勢
編輯HTTP摘要認證目的在於比傳統摘要認證構架更安全;例如,「明顯強於(如)CRAM-MD5……」。 (RFC 2617)
一些HTTP摘要認證的安全性增強如下:
- 密碼並非直接在摘要中使用,而是 HA1 = MD5(username:realm:password)。這就允許一些實現(如,JBoss DIGESTAuth(頁面存檔備份,存於網際網路檔案館))僅儲存 HA1 而不是明文密碼。
- 在 RFC 2617 中引入了客戶端亂數nonce(cnonce),這將使客戶端能夠防止選擇明文攻擊,否則像彩虹表(Rainbow table)這類東西就會成為摘要認證構架的威脅。
- 伺服器亂數 nonce 允許包含時間戳。因此伺服器可以檢查客戶端提交的亂數 nonce,以防止重放攻擊。
- 伺服器也可以維護一個最近發出或使用過的伺服器亂數nonce的列表以防止重用。
劣勢
編輯摘要訪問認證有意成為一個安全性的折衷。它意圖代替非加密的HTTP基本認證。但是,它沒有被設計為替換強認證協定,例如公鑰密碼學或Kerberos認證。
在安全性方面,摘要訪問認證有幾個缺點:
- RFC 2617 中的許多安全選項都是可選的。如果伺服器沒有指定保護品質(qop),客戶端將以降低安全性的早期的 RFC 2069 的模式操作。
- 摘要訪問認證容易受到中間人攻擊。舉例而言,一個中間人攻擊者可以告知客戶端使用基本訪問認證或早期的RFC 2069摘要訪問認證模式。進一步而言,摘要訪問認證沒有提供任何機制幫助客戶端驗證伺服器的身分。
- 一些伺服器要求密碼以可逆加密演算法儲存。但是,僅儲存使用者名稱、realm、和密碼的摘要是可能的。[2]
- 它阻止了使用強密碼雜湊函式(如bcrypt)儲存密碼(因為無論是密碼、或者使用者名稱、realm、密碼的摘要都要求是可恢復的)。
可替代的認證協定
編輯一些可以用於Web應用程式的強認證協定包括:
- 公鑰密碼學認證(通常隨 HTTPS / SSL客戶端整數一起實現)。
- Kerberos或SPNEGO認證,主要是在組態為Integrated Windows Authentication (IWA)的微軟的IIS使用。
- Secure Remote Password protocol (適用於HTTPS / TLS層)。
常用的弱明文協定:
使用HTTPS網路加密同時使用這些弱明文協定解決了許多摘要訪問認證試圖要防止的許多威脅。
範例及說明
編輯下面的例子出自 RFC 2617,在這裡進行了擴充,對每一個請求和回應顯示出完整的文字。注意,這裡僅僅涵蓋了「auth」保護品質的代碼,因為在撰寫期間,所知道的只有Opera和Konqueror網頁瀏覽器支援「auth-int」(帶完整性保護的認證)。雖然定義中提到了HTTP 1.1,但是該構架可以像下面所描述的這樣添加到1.0的伺服器中去。
典型的認證過程包括如下步驟。
- 客戶端請求一個需要認證的頁面,但是不提供使用者名稱和密碼。通常這是由於使用者簡單的輸入了一個位址或者在頁面中點擊了某個超連結。
- 伺服器返回401 "Unauthorized" 回應代碼,並提供認證域(realm),以及一個隨機生成的、只使用一次的數值,稱為密碼亂數 nonce。
- 此時,瀏覽器會向使用者提示認證域(realm)(通常是所訪問的電腦或系統的描述),並且提示使用者名稱和密碼。使用者此時可以選擇取消。
- 一旦提供了使用者名稱和密碼,客戶端會重新傳送同樣的請求,但是添加了一個認證頭包括了回應代碼。
- 在這個例子中,伺服器接受了認證並且返回了請求頁面。如果使用者名稱非法和/或密碼不正確,伺服器將返回"401"回應代碼,然後客戶端會再次提示使用者輸入使用者名稱及密碼。
注意:客戶端可能已經擁有了使用者名稱和密碼,因此不需要提示使用者,比如以前儲存在瀏覽器里的。
- 客戶端請求 (無認證)
GET /dir/index.html HTTP/1.0 Host: localhost
- 伺服器回應
HTTP/1.0 401 Unauthorized Server: HTTPd/0.9 Date: Sun, 10 Apr 2005 20:26:47 GMT WWW-Authenticate: Digest realm="testrealm@host.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41" Content-Type: text/html Content-Length: 311 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd(頁面存檔備份,存於網際網路檔案館)"> <HTML> <HEAD> <TITLE>Error</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>
- 客戶端請求 (使用者名稱 "Mufasa", 密碼 "Circle Of Life")
GET /dir/index.html HTTP/1.0 Host: localhost Authorization: Digest username="Mufasa", realm="testrealm@host.com", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", uri="/dir/index.html", qop=auth, nc=00000001, cnonce="0a4f113b", response="6629fae49393a05397450978507c4ef1", opaque="5ccc069c403ebaf9f0171e9517f40e41"
(跟隨一個新行,形式如前所述).
- 伺服器回應
HTTP/1.0 200 OK Server: HTTPd/0.9 Date: Sun, 10 Apr 2005 20:27:03 GMT Content-Type: text/html Content-Length: 7984
(隨後是一個空行,然後是所請求受限制的HTML頁面).
如下所述,response 值由三步計算而成。當多個數值合併的時候,使用冒號作為分割符。
- 對使用者名稱、認證域(realm)以及密碼的合併值計算 MD5 雜湊值,結果稱為 HA1。
- 對HTTP方法以及URI的摘要的合併值計算 MD5 雜湊值,例如,
"GET"
和"/dir/index.html"
,結果稱為 HA2。 - 對 HA1、伺服器密碼亂數(nonce)、請求計數(nc)、客戶端密碼亂數(cnonce)、保護品質(qop)以及 HA2 的合併值計算 MD5 雜湊值。結果即為客戶端提供的 response 值。
因為伺服器擁有與客戶端同樣的資訊,因此伺服器可以進行同樣的計算,以驗證客戶端提交的 response 值的正確性。在上面給出的例子中,結果是如下計算的。
(MD5()
表示用於計算 MD5 雜湊值的函式;「\」表示接下一行;引號並不參與計算)
完成 RFC 2617 中所給出的範例,將在每步得出如下結果。
HA1 = MD5( "Mufasa:testrealm@host.com:Circle Of Life" ) = 939e7578ed9e3c518a452acee763bce9 HA2 = MD5( "GET:/dir/index.html" ) = 39aff3a2bab6126f332b942af96d3366 Response = MD5( "939e7578ed9e3c518a452acee763bce9:\ dcd98b7102dd2f0e8b11d0f600bfb0c093:\ 00000001:0a4f113b:auth:\ 39aff3a2bab6126f332b942af96d3366" ) = 6629fae49393a05397450978507c4ef1
此時客戶端可以提交一個新的請求,重複使用伺服器密碼亂數(nonce)(伺服器僅在每次「401」回應後發行新的nonce),但是提供新的客戶端密碼亂數(cnonce)。在後續的請求中,十六進制請求計數器(nc)必須比前一次使用的時候要大,否則攻擊者可以簡單的使用同樣的認證資訊重放老的請求。由伺服器來確保在每個發出的密碼亂數nonce時,計數器是在增加的,並拒絕掉任何錯誤的請求。顯然,改變HTTP方法和/或計數器數值都會導致不同的 response 值。
伺服器應當記住最近所生成的伺服器密碼亂數nonce的值。也可以在發行每一個密碼亂數nonce後,記住過一段時間讓它們過期。如果客戶端使用了一個過期的值,伺服器應該回應「401」狀態號,並且在認證頭中添加stale=TRUE
,表明客戶端應當使用新提供的伺服器密碼亂數nonce重發請求,而不必提示使用者其它使用者名稱和口令。
伺服器不需要儲存任何過期的密碼亂數,它可以簡單的認為所有不認識的數值都是過期的。伺服器也可以只允許每一個伺服器密碼亂數nonce使用一次,當然,這樣就會迫使客戶端在傳送每個請求的時候重複認證過程。需要注意的是,在生成後立刻過期伺服器密碼亂數nonce是不行的,因為客戶端將沒有任何機會來使用這個nonce。
SIP 摘要認證
編輯瀏覽器實現
編輯大多數瀏覽器都基本上實現了該協定,除了某些特性,比如檢查auth-int、或者MD5-sess演算法。如果伺服器要求處理這類可選特性,客戶端可能無法進行認證(雖然需要注意的是,Apache伺服器的mod_auth_digest模組也沒有完全實現 RFC 2617)。