小話HTTP Authentication

什麼是Authentication?

首先解釋兩個長的很像、容易混淆的單詞,Authentication(鑑定、認證)Authorization(授權)

Authentication就是要證明你是誰。舉個例子,你告訴別人你的名字叫Alice,怎麼樣讓別人確信你就是Alice,這就是Authentication。

Authorization則是當別人已經相信是你以後,你是不是被允不允許做做某件事兒。比如,當你已經證明了你就是Alice了,你可以查你自己的信用卡刷卡記錄,但不能查Bob的刷卡記錄,這就是Authorization(當然,如果Alice是Bob的老婆這種情況除外)。


這篇博客就主要看看HTTP Authentication到底是怎麼回事。然後兩種常見的Authentication機制:HTTP Basic和Digest。


HTTP Basic

顧名思義,HTTP Basic指的就是最簡單的Authentication協議。簡單到什麼份兒上呢?直接方式告訴服務器你的用戶名(username)和密碼(password)。這裏假設我們的用戶名是Alice,密碼是123456。


我們使用curl訪問服務器

   curl -u Alice:123456 http://kiwiserver.com/secret -v


request頭部:

 GET /secret HTTP/1.1
 Authorization: Basic QWxpY2U6MTIzNDU2
 ...

我們這裏看到發送的request頭部中含有Authentication這個字段,其值爲Basic QWxpY2U6MTIzNDU2。Basic表示的使用的是HTTP Basic Authentication。而QWxpY2U6MTIzNDU2,則是由“Alice:123456”進行Base64編碼以後得到的結果。


response頭部: 

 HTTP/1.1 200 OK
 ...

因爲我們輸入的是正確的用戶名密碼,所以服務器會返回200,表示驗證成功。如果我們用錯誤的用戶的密碼來發送請求,則會得到類似如下含有401錯誤的response頭部:

 HTTP/1.1 401 Bad credentials
 WWW-Authenticate: Basic realm="Spring Security Application"
 ...


乍看起來好像HTTP Basic還挺不錯的,QWxpY2U6MTIzNDU2已經讓人很難看出來用戶名密碼是什麼了。但是,我們需要知道Base64編碼是可逆的。也就是我們可以通過decode Base64的編碼還原用戶名和密碼。

在命令行輸入如下命令:

   echo QWxpY2U6MTIzNDU2 | base64 -D

得到:

   Alice:123456

輕鬆解密。試想,如果一個人通過一定的方法截獲了Alice向服務器發送的請求,那不是很容易就能夠得到她的用戶名和密碼了嗎?所以,爲了保證用戶的安全,我們不會直接通過HTTP的方式使用Basic Authentication,而是會使用HTTPS,這樣更安全一些。



Replay Attack

通過前面介紹,我們知道了通過可逆的Base64的編碼方式不是太靠譜,那我們在發送密碼之前,將密碼用不可逆的方式進行編碼不就完了嗎?

比如,前面Alice的密碼是123456,進行MD5編碼

   md5 -s 123456

以後得到的就是

e10adc3949ba59abbe56e057f20f883e

這樣不就是不可逆的了?恩,即使有一個叫Craig的傢伙截獲了我向服務器發送的用戶名密碼,他也不知道我的密碼到底是什麼了。

的確,Craig拿到e10adc3949ba59abbe56e057f20f883e這個被md5 hash過的密碼也不知道Alice的密碼是什麼。但是,如果Craig直接拿着這個字符串放在HTTP頭部,再發送給服務器不就OK了?Craig這樣就根本不用解密這個密碼也能裝成“Alice”向服務器通信。這就叫做Replay Attack。



HTTP Digest

爲了避免被壞人使用Replay Attack,一個簡單的想法就是,讓我們每次向服務器發送的認證信息都“必須”是不一樣的,這樣Craig即使拿到了這個認證信息也沒有辦法進行replay attack了。那如何讓Alice每次向服務器發送的認證信息都是不一樣的,同時能夠讓服務器知道這就是Alice呢?

這就引出了Digest Authentication了。當Alice初次訪問服務器時,並不攜帶密碼。此時服務器會告知Alice一個隨機生成的字符串(nonce)。然後Alice再將這個字符串與她的密碼123456結合在一起進行MD5編碼,將編碼以後的結果發送給服務器作爲驗證信息。

因爲nonce是“每次”(並不一定是每次)隨機生成的,所以Alice在不同的時間訪問服務器,其編碼使用的nonce值應該是不同的,如果攜帶的是相同的nonce編碼後的結果,服務器就認爲其不合法,將拒絕其訪問。這樣,即使Craig能夠截獲Alice向服務器發送的請求,也沒有辦法使用replay attack冒充成Alice了。


我們還是可以使用curl來查看這一過程:

   curl -u Alice:123456 http://kiwiserver.com/secret -v --digest


curl和服務器通信過程

curl -------- request1:GET ------->> Server

curl <<------ response1:nonce ------- Server

curl ---- request2:Digest Auth ----> Server

curl <<------- response2:OK --------  Server


request1頭部:
 GET /secret HTTP/1.1
 ...
請求1中沒有包含任何用戶名和密碼信息

response1頭部:
 HTTP/1.1 401
Full authentication is required to access this resource
 WWW-Authenticate: Digest realm="Contacts Realm via Digest Authentication", qop="auth",nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA=="
 ...

當服務器接收到request1以後,認爲request1沒有任何的Authentication信息,所以返回401,並且告訴curl nonce的值是MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA

request2頭部:

 GET /secret HTTP/1.1
 Authorization: Digest username="Alice", realm="Contacts Realm via Digest Authentication",nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA==", uri="/secret", cnonce="MTQwMTk3", nc=00000001, qop="auth",response="fd5798940c32e51c128ecf88472151af"
 ...

curl接收到服務器的nonce值以後,就可以把如密碼等信息和nonce值放在一起然後進行MD5編碼,得到一個response值,如前面紅色標出所示,這樣服務器就可以通過這個值驗證Alice的密碼是否正確。


response2頭部:

 HTTP/1.1 200 OK
 ...


當我們完成Authentication以後,如果我們再次使用剛纔的nonce值:

   curl -X GET http://kiwisecrect.com/secret -H 'Authorization: Digest username="Alice", realm="Contacts Realm via Digest Authentication", nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA==", uri="/secret", cnonce="MTQwMTk3", nc=00000001, qop="auth", response="fd5798940c32e51c128ecf88472151af"' -v

收到錯誤信息:

 HTTP/1.1 401 Incorrect response
 WWW-Authenticate: Digest realm="Contacts Realm via Digest Authentication", qop="auth", nonce="MTQwMTk4Mjg4MjQ5NjpjZmNiNzI2ZmFlNzA4Nzg3ZDUxNjk2YTEyMTU3OTc0Yg=="


Digest Authentication比Basic安全,但是並不是真正的什麼都不怕了,Digest Authentication這種容易方式容易收到Man in the Middle式攻擊。(未完待續)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章