電腦本身沒辦法判斷正在使用電腦的人是誰,為了確認是否為本人,需要核對只有登入者本人才知道的訊息,核對訊息通常是以下:
HTTP 所使用的認證方式:
這個認證方法是從 HTTP/1.0 就定義的,現在還有一部分網站會用這種認證方法,就伺服器和客戶端進行的認證。
請求資料需要 BASIC 認證時,伺服器會隨著 401 狀態,回傳帶WWW-Authenticate
的字串,這個字段包含認證方式,以及 Request-URI 安全域字串。
接收到狀態 401 的客戶端為了通過驗證,需要把客戶 ID 及密碼傳送給伺服器,發送字串由 ID 及密碼組成,兩者中間以冒號連接後,再以 Base 64 編碼處理。
如果客戶 ID 是 guest,密碼是 guest,那連接後就是guest:guest
,再經過 Base64 編碼,最後再把編碼後的字串寫入首部字串Authenticate
後發送請求。當客戶代理為瀏覽器時,客戶僅輸入用戶 ID 和密碼即可,瀏覽器就會自動完成 Base64 編碼轉換的工作。
接收首部字串Authenticate
請求的伺服器,會對訊息的正確性進行驗證,通過驗證就會回傳包含一條 Request-URI 的資料回應。
因此這個認證達不到一般網站對於安全性的需求。
為了彌補 BASIC 認證的弱點,在 HTTP/1.1 就有 DIGEST 認證,使用質詢/回應的方式,不像 BASIC 認證直接發送明文。
質詢/回應:一方會先發認證給對方,接著從對方那邊接收到質詢碼計算產生回應碼,最後將回應碼回傳給對方進行認證。
請求需認證的資料,伺服器會隨著狀態碼 401,回傳帶WWW-Authenticate
的字串,這個字段包含質詢回應方式認證所需的臨時質詢碼(隨機)。
接收到 401 的客戶端,回傳回應包含 DIGEST 認證必要的字串 Authenticate
訊息。
Authenticate:必須包含 username、realm、nonce、uri 和 response 字串。
接收到包含Authenticate
請求的伺服器,會確認認證訊息的正確性,認證通過後再回傳含有 Request-URI 的資料回應,並在這時候回傳包含Authenticate-Info
的字串,裡面寫了一些認證相關訊息。
DIGEST 認證提供了高於 BASIC 認證的安全等級,但和 HTTPS 的客戶端認證相比,還是很薄弱,DIGEST 認證提供防止密碼被竊聽的機制,但他和 BASIC 認證一樣不敏捷,再來網站高度安全性的要求,還是有所落差,而且適用範圍也有限制。
以 ID 和密碼的認證來說,只要兩者都正確,就可以確認是本人行為,但是如果用戶 ID 和密碼被盜,就可能冒充,利用 SSL 客戶端認證就可以避免這種狀況。
SSL 客戶端認證是藉由 HTTPS 的客戶端憑證完成認證,伺服器就可以確認是否來自自己登入的客戶端。
為了能讓 SSL 客戶端認證,需要將客戶端憑證分發給客戶端,且客戶端需要安裝此憑證。
在多數狀況下,SSL 不會只依靠憑證,還跟後續會說到的表單驗證一起做,以達成雙因素認證,就可以確認是用戶本人的電腦在訪問伺服器。
雙因素認證:認證過程不僅需要密碼一個因素,還需要申請認證者提供其他持有訊息,當作另一個因素,一起結合使用的認證方式。
SSL 客戶端認證需要用到客戶端憑證,而憑證需要支付費用才能使用,每個認證機構的費用不盡相同,要維持安全的營運需要產生相應的費用。
表單驗證方法不是在 HTTP 協議中定義的,客戶端會向伺服端的網站發送登入訊息,按登入訊息的驗證結果認證。
雖然 HTTP 有提供 BASIC 認證和 DIGEST 認證,但幾乎不怎麼使用,但又由於 SSL 客戶端認證雖然有高度安全性,可是因為導入及費用的關係,還未普及。
以 SSH 和 FTP 協議來說,服務器與客戶端之間的認證是合乎標準,也滿足了基本功能的需求上的安全級別,因此這些協議可以直接拿來使用,由於網站的認證功能,能夠滿足安全級別的標準規範幾乎不存在,所以只好由網站各自實現表單的認證。
不具備共同標準的表單驗證,在每個網站上都有不一樣的方式,如果全面考慮安全性的表單驗證,也夠具備高度的安全等級,可是也有很多網站的表單驗證是有問題的。
由於表單驗證沒有一定的規範,一般會用 Cookie 來管理 Session。
基於表單驗證本身是通過伺服端的網站,將客戶端發送的用戶 ID 和密碼與之前登入的訊息座配對來進行認證,但有鑒於 HTTP 是無狀態協定,之前以經任正成功的用戶狀態沒有辦法保存下來,表示用戶下次訪問也沒辦法特別區隔,所以會用 Cookie 來管理 Session,以彌補 HTTP 協議中不存在的狀態管理功能。
客戶端把用戶 ID 和密碼等登入訊息放在 HTTP 訊息的實體,通常以 POST 方法把請求發送給伺服器,會使用 HTPPS 來進行 HTML 表單畫面的顯示和用戶輸入資料的發送。
伺服器會發放以用來識別用戶的 SessionID,通過驗證從客戶端發送過來的登入訊息進行身份驗證,接著把認證狀態和 SessionID綁定後記錄在伺服端。
客戶端回傳回應時,會在首部字串Set-Cookie
內寫入 Session ID,你可以想像 Session ID 是一個用來區分不同用戶的等位號。如果 Session ID 被第三方盜走,那麼對方可能會偽裝你的身份來進行惡意操作,為了預防這種狀況發生,Session ID 應該要用難以預測的字串,伺服端也要進行有效期的管理來保障安全。另外為了減輕 XSS 造成的損失,建議在 Cookie 上加上 httponly的屬性
客戶端接收從伺服端發來的 SessionID 後,會把這個當作 Cookie 保存在本地,下次伺服器發送請求時,瀏覽器會自動發送 Cookie,所以 SessionID 也會發送到伺服器,伺服端就可以驗證接收的 SessionID 以識別用戶跟狀態。
不僅基於表單認證的登入訊息和認證過程都沒有標準化,伺服端應該要如何保存用戶提交的密碼等登入訊息也沒有標準化。
通常安全地保存是給密碼加鹽(就是隨機產生字串讓他和密碼串相連)的方式增加額外的訊息,再使用散列(hash)函數去計算散列值之後保存,當然也有明文儲存密碼的方法,不過就可能會有風險。
資料來源:《圖解 HTTP》 上野宣 人民郵電出版社
筆記純屬推廣及分享,如有侵權,請告知。
Please advise to remove immediately if any infringement caused.