揭開HTTP網(wǎng)絡(luò)協(xié)議神秘面紗系列(四)
確保Web安全的HTTPS
HTTP存在三個比較明顯的缺點:
通信使用明文(不加密),內(nèi)容可能會被竊聽。
不驗證通信方的身份,因此有可能遭遇偽裝。
無法證明報文的完整性,所以可能已遭篡改。
盡管HTTP協(xié)議中沒有加密機制,但可以通過和SSL或TLS的組合使用加密HTTP的通信內(nèi)容,組合在一起通常被稱為HTTPS。
HTTP協(xié)議在通信過程會存在以下隱患:
無法確定請求發(fā)送至目標(biāo)的Web服務(wù)器是否是按真實意圖返回響應(yīng)的那臺服務(wù)器,有可能是已偽裝的Web服務(wù)器。
無法確定響應(yīng)返回到的客戶端是否是按真實意圖接受響應(yīng)的那個客戶端,有可能是已偽裝的客戶端。
無法確定正在通信的對方是否具備訪問權(quán)限,因為某些Web服務(wù)器上保存著重要的信息,只想發(fā)給特定用戶通信的權(quán)限。
無法判斷請求是來自何方,出自誰手。
即使是無意義的請求也會照單全收,無法阻止海量請求下的Dos攻擊(拒絕服務(wù)攻擊)。
請求或響應(yīng)內(nèi)容可能會在傳輸途中遭攻擊者攔截并篡改內(nèi)容。
HTTPS即使HTTP加上加密處理和認(rèn)證以及報文完整性保護(完整性是指信息的準(zhǔn)確度),其通信層次區(qū)別如圖:
SSL采用一種叫做公開密匙加密的加密處理方式,其加密算法是公開的,但密匙是保密的,加密和解密過程中都需要用到密匙。
加密和解密同用一個密鑰的方式稱為共享密鑰加密,也叫做對稱密鑰加密。
公開密鑰加密使用一對非對稱的密鑰,一把叫做私有密鑰,另一把叫做公開密鑰,私有密鑰不能讓其他任何人知道,而公開密鑰則可以隨意發(fā)布,任何都可以獲得,使用公開密鑰加密方式,發(fā)送密文的一方使用對方的公開密鑰進(jìn)行加密處理,對方收到加密的信息后,再使用自己的私有密鑰進(jìn)行解密,這種方式,不需要發(fā)送用來解密的私有密鑰,也不必?fù)?dān)心密鑰被攻擊者竊聽而盜走,其整個過程如圖:
HTTPS結(jié)合上面兩種加密方式采用混合加密機制,因為公開密使加密處理比共享密匙加密方式更復(fù)雜,效率較低,結(jié)合兩者的優(yōu)勢,HTTPS在交換密匙環(huán)節(jié)使用公開密鑰加密方式,之后的建立通信交換報文加段則使用共享密鑰加密方式,過程如圖:
為了認(rèn)證你訪問的服務(wù)器就是原本預(yù)想的那臺服務(wù)器,這就需要客戶端和服務(wù)器雙方都可信賴的第三方機構(gòu)——數(shù)字證書認(rèn)證機構(gòu),服務(wù)器會將這份由數(shù)字認(rèn)證機構(gòu)頒發(fā)的公鑰證書(也叫數(shù)字證書)發(fā)送給客戶端,以進(jìn)行公開密鑰加密方式通信,接到證書的客戶端可使用數(shù)字證書認(rèn)證機構(gòu)的公開密鑰,對那張證書書上的數(shù)字簽名進(jìn)行驗證,以但驗證通過,就說明服務(wù)器的公開密鑰是值得信賴以及服務(wù)器是你預(yù)想訪問的那個服務(wù),其整個過程如圖:
HTTPS通信大致步驟如下:
客戶端通過發(fā)送Client Hello報文開始SSL通信,報文中包含客戶端支持的SSL的指定版本,加密組件列表。
服務(wù)器可進(jìn)行SSL通信時,會以Sever Hello報文作為響應(yīng),和客戶端一樣,在報文中包含SSL版本以及加密組件,服務(wù)器的加密組件內(nèi)容是從接收到的客戶端加密組件內(nèi)選帥出來的。
之后服務(wù)器發(fā)送 Certificate報文,報文中包含公開密鑰 證書。
最后服務(wù)器發(fā)送Server Hello Done報文通知客戶端,最初階段的SSL握手協(xié)商部分結(jié)束。
SSL第一次握手結(jié)束之后,客戶端以Client Key Exchange報文作為回應(yīng),報文中包含通信加密中使用的一種稱為Pre-master secret的隨機密碼串,其過程用了來自服務(wù)器公開密鑰進(jìn)行加密。
接著客戶單繼續(xù)發(fā)送Change Cipher Spec報文,該報文會提示服務(wù)器,在此報文之后的通信會采用Pre-master secret密鑰加密。
客戶端發(fā)送Finished報文,該報文包含連接至今全部報文的整體校驗值,這次握手協(xié)商是否成功,要以服務(wù)器是否能夠正確加密該報文作為判定標(biāo)準(zhǔn)。
服務(wù)器同樣發(fā)送Change Cipher Spec報文。
服務(wù)器同樣發(fā)送Finished報文。
服務(wù)器和客戶端的Finished報文交換完畢之后,SSL連接就算建立完成,當(dāng)然,通信會受到SSL的保護,從此處開始進(jìn)行應(yīng)用層協(xié)議的通信,即發(fā)送HTTP請求。
應(yīng)用層協(xié)議通信,即發(fā)送HTTP響應(yīng)。
最后由客戶端斷開連接。
#p#
整個HTTPS通信大致過程如圖:
HTTPS由于使用SSL獨立協(xié)議,根據(jù)上面的處理過程,我們知道該協(xié)議需要大量消耗CPU及內(nèi)存資源等資源,故通信較慢,網(wǎng)絡(luò)負(fù)載較大。
確認(rèn)訪問用戶身份的認(rèn)證
HTTP協(xié)議通信過程會通過各種認(rèn)證方式來確定其身份,通常涉及到的核對信息有以下幾點:
密碼:只有本人才會知道的字符串信息。
動態(tài)令牌:僅限本人持有的設(shè)備內(nèi)顯示的一次性密碼。
數(shù)字認(rèn)證:僅限本人持有的信息。
生物認(rèn)證:指紋和虹膜等本人的生理信息。
IC 卡等:僅限本人持有的信息。
HTTPS一般的認(rèn)證方式:BASIC認(rèn)證(基本認(rèn)證),DIGEST認(rèn)證(摘要認(rèn)證),SSL客戶端認(rèn)證,F(xiàn)ormBase認(rèn)證(基于表單認(rèn)證)。
BASIC認(rèn)證步驟:
當(dāng)請求的資源需要BASIC認(rèn)證時,服務(wù)器會隨狀態(tài)碼401,返回帶WWW-Authenticate首部字段的響應(yīng),該字段內(nèi)包含認(rèn)證的方式(BASIC)及Request-URI安全域字符串(realm)。
接收到狀態(tài)碼401的客戶端為了通過BASIC認(rèn)證,需要將用戶ID及密碼發(fā)送給服務(wù)器,發(fā)送的字符串內(nèi)容是由用戶ID和密碼構(gòu)成,兩者中間以冒號(:)連接后,再經(jīng)過Base64編碼處理,如:用戶ID為guest,密碼是guest,連接起來就是guest:guest,然后會經(jīng)過瀏覽器Base64編碼后,發(fā)送請求。
接收到包含首部字段Authorization請求的服務(wù)器,會對認(rèn)證信息的正確性進(jìn)行驗證,驗證通過,則返回一條包含Request-URI資源的響應(yīng)。
整個認(rèn)證過程如圖:
BASIC認(rèn)證缺點:
在HTTP等非加密通信的線路上進(jìn)行這種認(rèn)證,容易被攔截竊聽。(注:Base64編碼用來加密,而是為能在通信傳輸信息)
瀏覽器無法實現(xiàn)認(rèn)證注銷操作。
DIGEST認(rèn)證步驟:
請求需認(rèn)證的資源時,服務(wù)器會隨狀態(tài)碼401,返回帶WWW-Authenticate首部字段的響應(yīng),該字段內(nèi)包含質(zhì)問響應(yīng)方式認(rèn)證所需的臨時質(zhì)詢碼(隨機數(shù),nonce).其中首部字段WWW-Authenticate內(nèi)必須包含realm和nonce這兩個字段(nonce是一種每次隨返回的401響應(yīng)生成的任意隨機字符串)。
接收到狀態(tài)碼401的客戶端,提取返回響應(yīng)中首部字段Authorization信息,并在自己的首部字段Authorization還必須加上usename,uri,response的字段信息(response也叫做Request-Digest,存放經(jīng)過MD5運算后的密碼字符串,形成響應(yīng)碼。)
接收到包含首部字段Authorization請求的服務(wù)器,會對認(rèn)證信息的正確性進(jìn)行驗證,驗證通過,則返回一條包含Request-URI資源的響應(yīng)。
整個認(rèn)證過程如圖:
DIGEST認(rèn)證比BASCI認(rèn)證安全性等級要高,能提供防止密碼被竊聽的保護機制,但是并不存在防止用戶偽裝的保護機制。
#p#
SSL客戶端認(rèn)證步驟:
接收到需要認(rèn)證資源的請求,服務(wù)器會發(fā)送Certificate Request報文,要求客戶端提供客戶端證書(需要向認(rèn)證機構(gòu)購買)
用戶選擇將發(fā)送的客戶端證書,客戶端會把客戶端證書信息以Client Certificate報文方式發(fā)送給服務(wù)器。
服務(wù)器驗證客戶端證書,驗證通過后方可領(lǐng)取證書內(nèi)的客戶端的公開密鑰,然后開始HTTPS加密通信。
SSL客戶端認(rèn)證需要客戶持有客戶端證書才能完成認(rèn)證,因此客戶需要在證書上支出費用。
表單認(rèn)證:
客戶端吧用戶ID和密碼等登陸信息放入報文的實體部分,通常是以POST方法把請求發(fā)送給服務(wù)器,這時,會使用HTTPS通信來進(jìn)行HTML表單畫面的顯示和用戶輸入數(shù)據(jù)的發(fā)送。
服務(wù)器會發(fā)放用以識別用戶的SessionID,通過驗證從客戶端發(fā)送過來的登陸信息進(jìn)行身份認(rèn)證,然后把用戶的認(rèn)證狀態(tài)與SessionID綁定后記錄在服務(wù)器端(向客戶端返回響應(yīng)時,會在首部字段Set-Cookie內(nèi)寫入SessionID)。
客戶端接收到從服務(wù)器端發(fā)來的SessionID后,會將其作為Cookie保存在本地,下次向服務(wù)器發(fā)送請求時,瀏覽器會自動發(fā)送Cookie,所以SessionID也隨之發(fā)送到服務(wù)器,服務(wù)器端通過此ID來驗證用戶。
表單認(rèn)證:表單認(rèn)證是最常見的認(rèn)證方式,該認(rèn)證方法并不是在HTTP協(xié)議中定義,它一般是由Web應(yīng)用提供登陸信息界面,使其更友好和用戶交互,用戶在其表單界面按提示和指導(dǎo)填寫完信息后,才提交到Web那邊應(yīng)用進(jìn)行驗證。
基于HTTP瓶頸
HTTP通信協(xié)議有下面幾點瓶頸:
一條連接上只可發(fā)送一個請求。
請求只能從客戶端開始,客戶端不可以接收除響應(yīng)外的指令。
請求/響應(yīng)首部未經(jīng)壓縮就發(fā)送,首部信息越多延遲越大。
發(fā)送冗長的首部,每次互相發(fā)送相同的首部造成的浪費較多。
可任意選擇數(shù)據(jù)壓縮格式,非強制壓縮發(fā)送。
引入Ajax技術(shù)來解決頁面局部更新,減少響應(yīng)中傳輸?shù)臄?shù)據(jù)(Ajax是一種有效利用JavaScript和DOM的操作,實現(xiàn)局部Web頁面替換加載的異步通信手段。)
引入Comet技術(shù)手段來解決實時更新問題,它通過延遲應(yīng)答,模擬實現(xiàn)服務(wù)器端向客戶端推送的功能,大致通信如下:
通常,服務(wù)器端接收到請求,在處理完畢后就會立即返回響應(yīng),但為了實現(xiàn)推送功能,Comet會先將響應(yīng)置于掛起狀態(tài),當(dāng)服務(wù)器有內(nèi)容更新時,再返回該響應(yīng),因此,服務(wù)器端一有更新,就可以立即反饋給客戶端。(因要保留響應(yīng),一次連接持續(xù)時間更長,故消耗更多的資源)。
SPDY技術(shù)引入可以讓HTTP獲得額外幾點功能,如下:
多路復(fù)用流:通過單一的TCP連接,可以無限制處理多個HTTP請求,所有請求的處理都在一條TCP連接上完成,因此TCP的處理效率提高。
賦予請求優(yōu)先級:SPDY通過給請求逐個分配優(yōu)先級順序,可以解決在同時刻發(fā)送多個請求,帶寬低而導(dǎo)致響應(yīng)慢的問題。
壓縮HTTP首部:壓縮HTTP請求和響應(yīng)的首部,能使通信產(chǎn)生的數(shù)據(jù)包數(shù)量和發(fā)送的字節(jié)數(shù)減少。
推送功能:支持服務(wù)器主動向客戶端推送數(shù)據(jù)的功能,這樣服務(wù)器就可以不用再等客戶端發(fā)送請求才返回數(shù)據(jù)了。
服務(wù)器提示功能:服務(wù)器可以主動提示客戶端請求所需資源的額更新情況,因此在客戶端對請求資源已緩存等情況下,可以避免發(fā)送不必要的請求。
引入WebSocket協(xié)議來解決HTTP一些瓶頸,該協(xié)議有主要特點如下:
*推送功能:支持服務(wù)器主動向客戶端推送數(shù)據(jù)的功能。
減少通信量:只要建立起WebSocket連接,就希望一直保持連接狀態(tài),和HTTP相比,不但每次連接時的總開銷減少,而且由于WebSocket的首部信息很小,通信量也減少了。
不過實現(xiàn)WebSocket通信是建立在HTTP基礎(chǔ)上,因此需要用HTTP的Upgrade首部字段告知服務(wù)器通信協(xié)議的改變,以達(dá)到握手的目的,整個過程如圖: