HTTPS,HTTP追加協議 - 重學計算機網絡系列(4)

前言

  • 本篇文章主要講HTTPS,HTTP和HTTPS區別,認證,SPDY的AJAX與Comet,Websocket

HTTPS

HTTP的缺點

通訊使用明文可能會被竊聽

因爲HTTP自己不具有加密的功能,因此也沒法作到對通訊總體(使用HTTP協議通訊的請求和響應的內容)進行加密。即,HTTP報文使用明文(指未通過加密的報文)方式發送。web

按TCP/IP協議族的工做機制,通訊內容在全部的通訊線路上都有可能遭到窺視。api

即便已通過加密處理的通訊,也會被窺視到通訊內容,這點和未加密的通訊是相同的。只是說若是通訊通過加密,就有可能讓人沒法破解報文信息的含義,但加密處理後的報文信息自己仍是會被看到的。瀏覽器

如何防止被竊聽

最爲普及的就是加密技術。安全

  • 通訊的加密
    HTTP協議中沒有加密機制,但能夠經過和SSL(Secure Socket Layer,安全套接層)或TLS(Transport Layer Security,安全傳輸層協議)的組合使用,加密HTTP的通訊內容。

用SSL創建安全通訊線路以後,就能夠在這條線路上進行HTTP通訊了。與SSL組合使用的HTTP被稱爲HTTPS(HTTP Secure,超文本傳輸安全協議)或HTTPover SSL。bash

  • 內容的加密
    因爲HTTP協議中沒有加密機制,那麼就對HTTP協議傳輸的內容自己加密。即把HTTP報文裏所含的內容進行加密處理。

誠然,爲了作到有效的內容加密,前提是要求客戶端和服務器同時具有加密和解密機制。主要應用在Web服務中。有一點必須引發注意,因爲該方式不一樣於SSL或TLS將整個通訊線路加密處理,因此內容仍有被篡改的風險。服務器

不驗證通訊方的身份

HTTP協議中的請求和響應不會對通訊方進行確認。websocket

任何人均可以發起請求

在HTTP協議通訊時,因爲不存在確認通訊方的處理步驟,任何人均可以發起請求。另外,服務器只要接收到請求,無論對方是誰都會返回一個響應(但也僅限於發送端的IP地址和端口號沒有被Web服務器設定限制訪問的前提下)。不確認通訊方,會存在如下各類隱患。網絡

  • 沒法肯定請求發送至目標的Web服務器是不是按真實意圖返回響應的那臺服務器。有多是已假裝的Web服務器。
  • 沒法肯定響應返回到的客戶端是不是按真實意圖接收響應的那個客戶端。有多是已假裝的客戶端。
  • 沒法肯定正在通訊的對方是否具有訪問權限。由於某些Web服務器上保存着重要的信息,只想發給特定用戶通訊的權限。
  • 沒法斷定請求是來自何方、出自誰手。
  • 即便是無心義的請求也會照單全收。沒法阻止海量請求下的DoS攻擊(Denial of Service,拒絕服務攻擊)。

如何驗證身份呢

雖然使用HTTP協議沒法肯定通訊方,但若是使用SSL則能夠。SSL不只提供加密處理,並且還使用了一種被稱爲證書的手段,可用於肯定方。多線程

證書由值得信任的第三方機構頒發,用以證實服務器和客戶端是實際存在的。另外,僞造證書從技術角度來講是異常困難的一件事。因此只要可以確認通訊方(服務器或客戶端)持有的證書,便可判斷通訊方的真實意圖。併發

報文可能會被篡改

因爲HTTP協議沒法證實通訊的報文完整性,所以,在請求或響應送出以後直到對方接收以前的這段時間內,即便請求或響應的內容遭到篡改,也沒有辦法獲悉。

好比,從某個Web網站上下載內容,是沒法肯定客戶端下載的文件和服務器上存放的文件是否先後一致的。文件內容在傳輸途中可能已經被篡改成其餘的內容。即便內容真的已改變,做爲接收方的客戶端也是覺察不到的。像這樣,請求或響應在傳輸途中,遭攻擊者攔截並篡改內容的攻擊稱爲中間人攻擊(Man-in-the-Middleattack,MITM)。

如何防止被篡改

雖然有使用HTTP協議(頭部字段Content-MD5)肯定報文完整性的方法,但事實上並不便捷、可靠。其中經常使用的是MD5和SHA-1等散列值校驗的方法,以及用來確認文件的數字簽名方法。

HTTPS = HTTP + 加密 + 認證 + 完整性保護

若是在HTTP協議通訊過程當中使用未經加密的明文,好比在Web頁面中輸入信用卡號,若是這條通訊線路遭到竊聽,那麼信用卡號就暴露了。

另外,對於HTTP來講,服務器也好,客戶端也好,都是沒有辦法確認通訊方的。由於頗有可能並非和本來預想的通訊方在實際通訊。而且還須要考慮到接收到的報文在通訊途中已經遭到篡改這一可能性。

爲了統一解決上述這些問題,須要在HTTP上再加入加密處理和認證等機制。咱們把添加了加密及認證機制的HTTP稱爲HTTPS(HTTP Secure)

HTTPS是身披SSL外殼的HTTP

HTTPS並不是是應用層的一種新協議。只是HTTP通訊接口部分用SSL(Secure Socket Layer)和TLS(TransportLayer Security)協議代替而已。

一般,HTTP直接和TCP通訊。當使用SSL時,則演變成先和SSL通訊,再由SSL和TCP通訊了。簡言之,所謂HTTPS,其實就是身披SSL協議這層外殼的HTTP。

SSL是獨立於HTTP的協議,因此不光是HTTP協議,其餘運行在應用層的SMTP和Telnet等協議都可配合SSL協議使用。能夠說SSL是當今世界上應用最爲普遍的網絡安全技術。

HTTPS和HTTP的區別

  • HTTPS協議須要到CA(證書頒發機構)申請證書,通常免費證書不多,須要交費。
  • HTTP協議運行在TCP之上,全部傳輸的內容都是明文,HTTPS運行在SSL/TLS之上,SSL/TLS運行在TCP之上,全部傳輸的內容都通過加密的。
  • HTTP和HTTPS使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。
  • http的鏈接很簡單,是無狀態的;HTTPS協議是由HTTP+SSL協議構建的可進行加密傳輸、身份認證的網絡協議,能夠有效的防止運營商劫持,解決了防劫持的一個大問題,比http協議安全。

認證

何爲認證

計算機自己沒法判斷坐在顯示器前的使用者的身份。進一步說,也沒法確認網絡的那頭究竟有誰。可見,爲了弄清到底是誰在訪問服務器,就得讓對方的客戶端自報家門。

爲確認用戶是否真的具備訪問系統的權限,就須要覈對「登陸者本人才知道的信息」、「登陸者本人才會有的信息」

覈對的信息一般是指如下這些。

  • 密碼:只有本人才會知道的字符串信息。
  • 動態令牌:僅限本人持有的設備內顯示的一次性密碼。
  • 數字證書:僅限本人(終端)持有的信息。
  • 生物認證:指紋和虹膜等本人的生理信息。
  • IC卡等:僅限本人持有的信息。

HTTP/1.1使用的認證方式

  • BASIC認證(基本認證)
  • DIGEST認證(摘要認證)
  • SSL客戶端認證
  • FormBase認證(基於表單認證)

BASIC認證

BASIC認證(基本認證)是從HTTP/1.0就定義的認證方式。即使是如今仍有一部分的網站會使用這種認證方式。是Web服務器與通訊客戶端之間進行的認證方式。

  • 步驟1:當請求的資源須要BASIC認證時,服務器會隨狀態碼401 Authorization Required,返回帶WWW-Authenticate首部字段的響應。該字段內包含認證的方式(BASIC)及Request-URI安全域字符串(realm)。
  • 步驟二: 接收到狀態碼401的客戶端爲了經過BASIC認證,須要將用戶ID及密碼發送給服務器。發送的字符串內容是由用戶ID和密碼構成,二者中間以冒號(:)鏈接後,再通過Base64編碼處理。當用戶代理爲瀏覽器時,用戶僅需輸入用戶ID和密碼便可,以後,瀏覽器會自動完成到Base64編碼的轉換工做。
  • 步驟3:步驟3: 接收到包含首部字段Authorization請求的服務器,會對認證信息的正確性進行驗證。如驗證經過,則返回一條包含Request-URI資源的響應。

BASIC認證雖然採用Base64編碼方式,但這不是加密處理。不須要任何附加信息便可對其解碼。換言之,因爲明文解碼後就是用戶ID和密碼,在HTTP等非加密通訊的線路上進行BASIC認證的過程當中,若是被人竊聽,被盜的可能性極高

BASIC認證使用上不夠便捷靈活,且達不到多數Web網站指望的安全性等級,所以它並不經常使用。

DIGEST認證

爲彌補BASIC認證存在的弱點,從HTTP/1.1起就有了DIGEST認證。DIGEST認證一樣使用質詢/響應的方式,但不會像BASIC認證那樣直接發送明文密碼

所謂質詢響應方式是指,一開始客戶端會先發送認證要求給服務端,服務端發送質詢碼給客戶端,接着客戶端使用接收到的質詢碼計算生成響應碼。最後將響應碼返回給對方進行認證的方式。

  • 步驟1:請求需認證的資源時,服務器會隨着狀態碼401 Authorization Required,返回帶WWW-Authenticate首部字段的響應。
  • 步驟2: 接收到401狀態碼的客戶端,返回的響應中包含DIGEST認證必須的首部字段Authorization信息。
  • 步驟3: 接收到包含首部字段Authorization請求的服務器,會確認認證信息的正確性。認證經過後則返回包含Request-URI資源的響應。

DIGEST認證提供了高於BASIC認證的安全等級,可是和HTTPS的客戶端認證相比仍舊很弱。DIGEST認證提供防止密碼被竊聽的保護機制,但並不存在防止用戶假裝的保護機制。

SSL客戶端認證

從使用用戶ID和密碼的認證方式方面來說,只要兩者的內容正確,便可認證是本人的行爲。但若是用戶ID和密碼被盜,就頗有可能被第三者冒充。利用SSL客戶端認證則能夠避免該狀況的發生。

SSL客戶端認證是藉由HTTPS的客戶端證書完成認證的方式。憑藉客戶端證書(在HTTPS一章已講解)認證,服務器可確認訪問是否來自已登陸的客戶端。

  • 步驟1: 接收到須要認證資源的請求,服務器會發送Certificate Request報文,要求客戶端提供客戶端證書。
  • 步驟2: 用戶選擇將發送的客戶端證書後,客戶端會把客戶端證書信息以Client Certificate報文方式發送給服務器。
  • 步驟3: 服務器驗證客戶端證書驗證經過後方可領取證書內客戶端的公開密鑰,而後開始HTTPS加密通訊

使用SSL客戶端認證須要用到客戶端證書。而客戶端證書須要向認證機構購買。

表單認證

基於表單的認證方法並非在HTTP協議中定義的。客戶端會向服務器上的Web應用程序發送登陸信息(Credential),按登陸信息的驗證結果認證。

多數狀況下,輸入已事先登陸的用戶ID(一般是任意字符串或郵件地址)和密碼等登陸信息後,發送給Web應用程序,基於認證結果來決定認證是否成功。

認證多半爲表單認證

因爲使用上的便利性及安全性問題,HTTP協議標準提供的BASIC認證和DIGEST認證幾乎不怎麼使用。另外,SSL客戶端認證雖然具備高度的安全等級,但由於導入及維持費用等問題,還還沒有普及。

Session(會話)管理及Cookie應用

基於表單認證自己是經過服務器端的Web應用,將客戶端發送過來的用戶ID和密碼與以前登陸過的信息作匹配來進行認證的。

但鑑於HTTP是無狀態協議,以前已認證成功的用戶狀態沒法經過協議層面保存下來。即,沒法實現狀態管理,所以即便當該用戶下一次繼續訪問,也沒法區分他與其餘的用戶。因而咱們會使用Cookie來管理Session,以彌補HTTP協議中不存在的狀態管理功能。

  • 步驟1: 客戶端把用戶ID和密碼等登陸信息放入報文的實體部分,一般是以POST方法把請求發送給服務器。而這時,會使用HTTPS通訊來進行HTML表單畫面的顯示和用戶輸入數據的發送。
  • 步驟2: 服務器會發放用以識別用戶的Session ID。經過驗證從客戶端發送過來的登陸信息進行身份認證,而後把用戶的認證狀態與Session ID綁定後記錄在服務器端。
  • 步驟3: 客戶端接收到從服務器端發來的Session ID後,會將其做爲Cookie保存在本地。下次向服務器發送請求時,瀏覽器會自動發送Cookie,因此SessionID也隨之發送到服務器。服務器端可經過驗證接收到的Session ID識別用戶和其認證狀態。

基於HTTP的功能追加協議

在創建HTTP標準規範時,制訂者主要想把HTTP看成傳輸HTML文檔的協議。隨着時代的發展,Web的用途更具多樣性,好比演化成在線購物網站、SNS(SocialNetworking Service,社交網絡服務)、企業或組織內部的各類管理工具,等等。

而這些網站所追求的功能可經過Web應用和腳本程序實現。即便這些功能已經知足需求,在性能上卻未必最優,這是由於HTTP協議上的限制以及自身性能有限。

HTTP功能上的不足可經過建立一套全新的協議來彌補。但是目前基於HTTP的Web瀏覽器的使用環境已遍及全球,所以沒法徹底拋棄HTTP。有一些新協議的規則是基於HTTP的,並在此基礎上添加了新的功能。

SPDY

Google在2010年發佈了SPDY,其開發目標旨在解決HTTP的性能瓶頸,縮短Web頁面的加載時間(50%)。

背景

在Facebook和Twitter等SNS網站上,短的時間內就會發生大量的內容更新。

爲了儘量實時地顯示這些更新的內容,服務器上一有內容更新,就須要直接把那些內容反饋到客戶端的界面上。雖然看起來挺簡單的,但HTTP卻沒法妥善地處理好這項任務。

使用HTTP協議探知服務器上是否有內容更新,就必須頻繁地從客戶端到服務器端進行確認。若是服務器上沒有內容更新,那麼就會產生徒勞的通訊。

HTTP的瓶頸

  • 一條鏈接上只可發送一個請求。
  • 請求只能從客戶端開始。客戶端不能夠接收除響應之外的指令。
  • 請求/響應首部未經壓縮就發送。首部信息越多延遲越大。
  • 發送冗長的首部。每次互相發送相同的首部形成的浪費較多。
  • 可任意選擇數據壓縮格式。非強制壓縮發送。

那麼SPDY如何解決這些瓶頸呢?

  • AJAX
  • Comet

SPDY沒有徹底改寫HTTP協議,而是在TCP/IP的應用層與傳輸層之間經過新加會話層的形式運做。同時,考慮到安全性問題,SPDY規定通訊中使用SSL。

SPDY以會話層的形式加入,控制對數據的流動,但仍是採用HTTP創建通訊鏈接。所以,可照常使用HTTP的GET和POST等方法、Cookie以及HTTP報文等。

SPDY的優勢

  • 多路複用流。
    經過單一的TCP鏈接,能夠無限制處理多個HTTP請求。全部請求的處理都在一條TCP鏈接上完成,所以TCP的處理效率獲得提升。

  • 請求優先級
    SPDY不只能夠無限制地併發處理請求,還能夠給請求逐個分配優先級順序。這樣主要是爲了在發送多個請求時,解決因帶寬低而致使響應變慢的問題。

  • 壓縮HTTP首部
    這樣一來,通訊產生的數據包數量和發送的字節數就更少了。

  • 推送功能
    支持服務器主動向客戶端推送數據的功能。這樣,服務器可直接發送數據,而沒必要等待客戶端的請求。

AJAX技術

AJAX不是JavaScript的規範,它只是一個哥們「發明」的縮寫:Asynchronous JavaScript and XML,意思就是用JavaScript執行異步網絡請求

Ajax(Asynchronous JavaScript and XML,異步JavaScript與XML技術)是一種有效利用JavaScript和DOM(Document Object Model,文檔對象模型)的操做,以達到局部Web頁面替換加載的異步通訊手段。和之前的同步通訊相比,因爲它只更新一部分頁面,響應中傳輸的數據量會所以而減小,這一優勢顯而易見。

Ajax的核心技術是名爲XMLHttpRequest的API,經過JavaScript腳本語言的調用就能和服務器進行HTTP通訊。藉由這種手段,就能從已加載完畢的Web頁面上發起請求,只更新局部頁面。

引用廖雪峯老師的例子(利用XMLHttpRequest來作請求)
'use strict';
----
function success(text) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = text;
}

function fail(code) {
    var textarea = document.getElementById('test-response-text');
    textarea.value = 'Error code: ' + code;
}

var request = new XMLHttpRequest(); // 新建XMLHttpRequest對象

request.onreadystatechange = function () { // 狀態發生變化時,函數被回調
    if (request.readyState === 4) { // 成功完成
        // 判斷響應結果:
        if (request.status === 200) {
            // 成功,經過responseText拿到響應的文本:
            return success(request.responseText);
        } else {
            // 失敗,根據響應碼判斷失敗緣由:
            return fail(request.status);
        }
    } else {
        // HTTP請求還在繼續...
    }
}

// 發送請求:
request.open('GET', '/api/categories');
request.send();

alert('請求已發送,請等待響應...');
複製代碼

Comet

一旦服務器端有內容更新了,Comet不會讓請求等待,而是直接給客戶端返回響應。這是一種經過延遲應答,模擬實現服務器端向客戶端推送(Server Push)的功能

一般,服務器端接收到請求,在處理完畢後就會當即返回響應,但爲了實現推送功能,Comet會先將響應置於掛起狀態,當服務器端有內容更新時,再返回該響應。所以,服務器端一旦有更新,就能夠當即反饋給客戶端。

內容上雖然能夠作到實時更新,但爲了保留響應,一次鏈接的持續時間也變長了。期間,爲了維持鏈接會消耗更多的資源。

WebSocket

產生背景

不少網站爲了實現推送技術,所用的技術都是輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。

而比較新的技術去作輪詢的效果是Comet。這種技術雖然能夠雙向通訊,但依然須要反覆發出請求。並且在Comet中,廣泛採用的長連接,也會消耗服務器資源。

Comet本質上也是輪詢,可是在沒有消息的狀況下,服務器先拖一段時間,等到有消息了再回復。這個機制暫時地解決了實時性問題,可是它帶來了新的問題:以多線程模式運行的服務器會讓大部分線程大部分時間都處於掛起狀態,極大地浪費服務器資源。另外,一個HTTP鏈接在長時間沒有數據傳輸的狀況下,鏈路上的任何一個網關均可能關閉這個鏈接,而網關是咱們不可控的,這就要求Comet鏈接必須按期發一些ping數據表示鏈接「正常工做」。

在這種狀況下,HTML5定義了WebSocket協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。

WebSocket鏈接建立過程

  • WebSocket鏈接必須由瀏覽器發起,由於請求協議是一個標準的HTTP請求,格式以下:
GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13
複製代碼
  • 該請求和普通的HTTP請求有幾點不一樣:
    • GET請求的地址不是相似/path/,而是以ws://開頭的地址
    • 請求頭Upgrade: websocket和Connection: Upgrade表示這個鏈接將要被轉換爲WebSocket鏈接;
    • Sec-WebSocket-Key是用於標識這個鏈接,並不是用於加密數據;
    • Sec-WebSocket-Version指定了WebSocket的協議版本。
  • 隨後,服務器若是接受該請求,就會返回以下響應:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string
複製代碼

響應代碼101表示本次鏈接的HTTP協議即將被更改,更改後的協議就是Upgrade: websocket指定的WebSocket協議

版本號和子協議規定了雙方能理解的數據格式,以及是否支持壓縮等等。若是僅使用WebSocket的API,就不須要關心這些。

如今,一個WebSocket鏈接就創建成功,瀏覽器和服務器就能夠隨時主動發送消息給對方。消息有兩種,一種是文本,一種是二進制數據。一般,咱們能夠發送JSON格式的文本,這樣,在瀏覽器處理起來就十分容易。

原理

WebSocket並非全新的協議,而是利用了HTTP協議來創建鏈接。

WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。

在 WebSocket API 中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。

因爲是創建在HTTP基礎上的協議,所以鏈接的發起方還是客戶端,而一旦確立WebSocket通訊鏈接,不論服務器仍是客戶端,任意一方均可直接向對方發送報文。

爲何WebSocket鏈接能夠實現全雙工通訊而HTTP鏈接不行呢?實際上HTTP協議是創建在TCP協議之上的,TCP協議自己就實現了全雙工通訊,可是HTTP協議的請求-應答機制限制了全雙工通訊。WebSocket鏈接創建之後,其實只是簡單規定了一下:接下來,我們通訊就不使用HTTP協議了,直接互相發數據吧

安全的WebSocket鏈接機制和HTTPS相似。首先,瀏覽器用wss://xxx建立WebSocket鏈接時,會先經過HTTPS建立安全的鏈接,而後,該HTTPS鏈接升級爲WebSocket鏈接,底層通訊走的仍然是安全的SSL/TLS協議。

特色

  • 推送功能
    支持由服務器向客戶端推送數據的推送功能。這樣,服務器可直接發送數據,而沒必要等待客戶端的請求。

  • 減小通訊量
    只要創建起WebSocket鏈接,就但願一直保持鏈接狀態。和HTTP相比,不但每次鏈接時的總開銷減小,並且因爲WebSocket的首部信息很小,通訊量也相應減小了。

成功握手確立WebSocket鏈接以後,通訊時再也不使用HTTP的數據幀,而採用WebSocket獨立的數據幀。

很顯然,要支持WebSocket通訊,瀏覽器得支持這個協議,這樣才能發出ws://xxx的請求。目前,支持WebSocket的主流瀏覽器以下:

  • Chrome
  • Firefox
  • IE >= 10
  • Sarafi >= 6
  • Android >= 4.4
  • iOS >= 8

HTTP/2.0

HTTP/2.0在2014年11月實現標準化。

HTTP/2.0的目標是改善用戶在使用Web時的速度體驗。

有如下幾個目標:

  • 異步鏈接多路複用
  • 頭部壓縮;
  • 請求/響應管線化
相關文章
相關標籤/搜索