1. 程式人生 > >HTTP HTTPS詳解

HTTP HTTPS詳解

一、背景

       作為一名Web開發人員,感覺自己不夠合格。為什麼要這麼說呢?因為迄今為止,自己對於HTTP與 HTTPS 的區別還是很模糊。碰巧最近在做的一個專案需要由HTTP遷到HTTPS下,正好趁此機會好好捋一下兩者的區別。

      OK,今天的學習將圍繞以下幾方面展開:

  • 什麼是HTTP
  • 什麼是HTTPS
  • HTTPS 如何加密的
  • 什麼是CA
  • TCP連線的建立

二、什麼是 HTTP


       HTTP(HyperText Transfer Protocol) 指的是超文字傳輸

協議,是一種無狀態,無連線的一種應用層協議。

       無連線指的是在 HTTP1.0 版本中,每次建立起的 TCP 連線只處理一個請求,服務端在收到客戶端的應答之後就立即斷開連結。假如一個網頁內有十張圖片,那麼需要建立-斷開連結十一次。

       很顯然,這種機制無法應對目前豐富的網頁內容。每一個網頁都包含大量的資原始檔,如果每個連線僅傳輸一個檔案就斷開太過於浪費伺服器資源了。所以,在 HTTP1.1 中支援了永續性連線(也就是長連結)。詳細點說就是如果HTTP 頭部行中Connection 欄位為 keep-alive,服務端在傳輸完第一個資源後不會立即斷開 TCP 連線,會稍微等待一會(5秒或伺服器自定義配置的時間)。如果瀏覽器在這個時間段內還要請求一些其他資源(如圖片),就會繼續使用這個連線進行資料的傳輸,超過設定的時間之後連結就會斷開。這樣就節省了多次建立-斷開連線所消耗的時間和資源開銷。

       無狀態是指伺服器不記錄任何有關客戶端先前傳送過的請求。每一次連線都是新的,都是你要什麼資源,我給你什麼資源。我不管你是誰,也不知道你是誰,更不知道你之前是否向我要過同一個資源。

       為什麼採用無狀態的機制呢,我們可以和有狀態的協議作對比。有狀態的協議更加複雜,伺服器需要維護和記錄狀態資訊。一旦伺服器或客戶端出現了故障,如重啟,就會產生狀態不一致的情況,狀態不一致的話,就會出現錯誤,為了保證狀態的一致性,還需要重新維護狀態記錄。舉一個例子,我向伺服器請求了一個資源,伺服器記錄了我已經請求過了這個資源併發送給我,過了一小會,這個資源被我不小心刪了,我需要重新向伺服器請求這個資源,但伺服器並不理我,因為在他的記錄中,我剛請求過這個資源,他已經發送過了,不會再發一遍了。這時候就出現了問題,為了讓他再發一份,我還需要跟伺服器協商,說我現在的確沒有這個資源,我這個資源因為某種原因沒有了,你在給我重新發一份吧,只有這樣,伺服器才會更新一下狀態,重新給我發一份。上述情況是在有狀態協議機制下可能出現的情況。當然,有狀態的協議也有很多好處,比如避免了向同一使用者頻繁傳送相同資源的情況,節約了頻寬。每一個協議都有其優點和缺點。HTTP 無狀態的特性,使其協議更加的簡單,也帶來了一定的缺陷,就是伺服器無法識別出來你是誰,無法識別你的身份,HTTP 在後來加入了 Cookie 機制,較好的解決了這一問題。

        HTTP 處於 ISO 制定的七層模型中的最頂層 —— 應用層,同處於應用層的協議還包括 FTP,SMTP。這個七層模型是用於計算機之間互聯的一個標準體系,詳細可以參考:關於OSI七層模型你應該知道的東西

什麼是 HTTPS


       HTTPS 指的是超文字傳輸安全協議(Hypertext Transfer Protocol Secure)。簡單的理解,HTTPS 就是將 HTTP 中的傳輸內容通過TLS進行加密,然後通過可靠的TCP連線,傳輸到對方的機器上。
       相比HTTP多了一個S,那這個 S 到底做了什麼呢? S 指的就是按照 TSL協議對資料進行加密操作。在TLS中,主要實現的就是加密的過程。加密過程中用到了「非對稱加密」和「對稱加密」兩種加密方式。

        對稱加密思路比較簡單,就是大家約定一個密碼進行加密,然後用同一個密碼在進行解密,邏輯比較簡單。

        非對稱加密相對麻煩和消耗CPU資源,非對稱加密方法一開始會生成一對金鑰,也就是兩個密碼。加密解密過程會用這兩個金鑰來完成。如果你用第一把鑰匙加密,那麼你只能用第二把鑰匙才能解開。你用第二把鑰匙加密,只能用第一把鑰匙解開,這是非對稱加密的表現。

       在非對稱加密演算法中應用最廣泛的是 RSA 加密演演算法,破解難度隨著金鑰的長度指數性增加,暫時很難被破解。但它並不是完美的,RSA 的缺陷是在資料加密解密的過程中需要耗費大量的計算資源,也就是 CPU 資源,所以對伺服器的效能會有較大的影響,如果所有資料都用 RSA 加密的話,會對伺服器會產生十分巨大的壓力,雖然安全了,但效能下降了。

       實際中我們是非對稱加密和對稱加密結合使用的:先使用非對稱加密演算法將某一密文加密,之後所有資料都採用該密文進行對稱加密/解密。這樣,既保證了效能,又保證了安全性。

       在採用非對稱加密演算法生成倆個鑰匙之後,網站需要公佈出去其中一把鑰匙,我們把公佈出去的密碼稱之為公鑰,自己留著的那一把鑰匙稱之為私鑰。我們向全世界廣播我們網站公鑰是什麼,大家都可以通過這個公鑰對要傳輸的資料進行加密,然後我們網站內部會有一個私鑰,可以通過私鑰解密公鑰加密的資料。怎麼將公鑰交給你呢,就是瀏覽器和伺服器建立起了連線之後,伺服器會先發送一個資訊,就是自己的公鑰(公開的密碼),然後瀏覽器拿到這個密碼對資料進行加密,加密之後傳輸給伺服器。伺服器收到密文之後用自己的私鑰解密資料,獲得真實資料,完成了加密傳輸的想法。

       但是我們仔細想一想,作為第三方偷窺者,他還是有可能破解我們傳輸的資訊。為什麼呢,因為在傳輸公鑰的過程中,第三方截取了公鑰,然後隨便給你發一個密碼,你會以為這個密碼就是伺服器發來的,伺服器也不知道密碼被截獲了。在傳輸訊息時,仍然按私鑰加密,由於第三方擁有伺服器的公鑰,就可以得到資料內容,之後在將資料用剛剛隨便發給你的密碼就行加密,你拿到資料之後,發現能用第三方發給的密碼解開資料,你還自以為和伺服器一直在“加密”通訊呢。如何解決呢,引出了下文。

什麼是CA


       數字證書認證機構(Certificate Authority,縮寫為CA)。我們知道,伺服器不能將非對稱加密產生的公鑰直接告訴你,因為中間人可能截獲這個公鑰進行解密篡改,加密,傳輸。所以想一個下下策了,成立一個官方組織,由它來作認定。伺服器會將產生的公鑰交給他,讓他進行登記,他登記後會給我發一個證書,來證明我是我。證書中含有我的公鑰內容,還包含一些其他資訊,比如我是哪個公司的,域名是什麼,誰給我的這個證書等等。本來我應該給你公鑰的,現在變了,我給你傳送一個我的證書,你拿著這個證書去找 CA 質問,這個證書是真的嗎,CA 會匹配公鑰和證書內的其他資訊,看是否真的在他那兒註冊過了,如果確認是真的,那就說明證書沒被中間人篡改,那你就可以大膽的用證書中的公鑰進行加密。

       當然,數字證書也可能被第三方截獲,第三方也得到公鑰資訊,也可以解密伺服器傳來的資訊,那麼,我們讓瀏覽器先設定對稱加密的密碼的,將密碼用公鑰加密,傳輸給伺服器,第三方只有公鑰,解不開密碼,而伺服器可以解開,之後就可以通過對稱加密的方式進行通訊了,我們就可以安全的傳輸資料了,再也不怕中間人偷窺了。一般瀏覽器在作業系統中內建的一些頂級 CA 資訊來驗證對方證書的真實性,如果證書有問題,瀏覽器會發出提示。

HTTP 和 HTTPS 連線建立


HTTP 在傳輸層之上,是依靠於 TCP 連線的。也就是說先建立起 TCP 連線,建立好連線之後雙方之間才能傳輸資料。也就是說,想按照規定的格式傳輸資料,就需要先建立 TCP 連線。那 TCP 連線是怎麼建立起來的呢。具體過程是這個樣子:我們在瀏覽器上輸入了要訪問的網站地址之後,瀏覽器會向 DNS 伺服器請求這個域名對應的 IP 地址,拿到 IP 地址就相當於知道了對方的位置。我們就可以向他傳送一個建立連線的請求,同時自己也做好了要建立連線的「準備」。這是第一步,向對方傳送一個建立連線的請求。對方機器一直在等待著其他人跟自己建立連線,等啊等,突然收到了你要建立連線的請求,興奮不已,立刻回覆你,說:我收到了你要建立連線的請求啦,我也準備好要建立連線啦。這是第二步。你收到這個訊息之後一定要回復它,說:好的,我知道你也做好了建立連線的準備啦,咱們開始傳送資料吧。這是第三步。為什麼一定要回復他呢,因為他不確定你是否收到了他的確認請求,如果你不回覆,他會以為你這個建立請求的訊息是假的,是過期了的,就不會建立連線。當他收到你的回覆之後,就明確的知道了你確實要建立連線,也知道了你準備好了連線的建立,再之後就可以按照 HTTP 的格式傳輸資料了。在這個過程中的第三步時,就是你傳送確認訊息的那個資料包中,可以將需要傳輸的資料一併塞進去的。這個就是 TCP 連線的三次握手。在重複一次,你先發一個建立連線的請求,他接收後回覆一個收到,建立吧,你收到他的回覆,在向他回覆一個知道啦。這時,你們之間 TCP 連線就已經建立好了。接下來,你就可以按照 HTTP 向他傳送請求,比如說要某一個圖片,他收到請求後就會給你發過來一個圖片,當然,你們之間是明文傳輸的。

那 HTTPS 是如何建立連線的呢,怎麼商量好加密密碼的呢?HTTPS 同 HTTP 一樣,首先建立起 TCP 連線,但是建立好之後並不是立即發出請求,索要具體的資源,而是先和對方商量加密的密碼。商量的加密密碼的過程就是建立 TSL 連線的過程。其實並沒有建立真實的連線,只是在剛剛建立好的 TCP 連線上,包裹上一層加密協議而已。但是也被形象的稱作連線建立。具體建立方式如下:客服端發給伺服器一個HELLO包,裡面有我支援的加密協議列表。伺服器收到後傳送也給客戶端傳送一個HELLO資料包,資料包內包涵伺服器挑選的加密演算法,還包含自己的數字證書資訊。你拿到他的數字證書資訊之後就需要去向 CA 校驗證書,校驗成功後也知道了對方的公鑰,就該通知伺服器,我們以後對稱加密的密碼是多少,當然,這個密碼是要用公鑰加密的。在這條訊息傳送之前,客戶端會先發送一條訊息,告訴伺服器,我下一個訊息將使用你剛剛挑選的加密協議進行加密了,下一個訊息是加密後的哦,不要搞錯。之後將對稱加密的密文發給伺服器。伺服器接收到之後,會根據對稱金鑰生成一系列複雜的加密演算法,在傳輸給客服端,客戶端收到後會給伺服器傳送一個 Finished Message ,伺服器收到訊息後也回一個 Finished Message。這時,我們終於完成了加密的準備工作,一切加密方式和金鑰都商量好了,終於可以傳輸資料了。至此,TSL 建立連線的過程結束。