1. 程式人生 > >揭開HTTPS的神祕面紗

揭開HTTPS的神祕面紗

在說HTTP前,一定要先介紹一下HTTP,這傢伙應該不用過多說明了,大家每天都在用,每一次HTTP請求,都是一次TCP連線。遺憾的是,請求的內容在TCP報文中是明文傳輸的,任何人擷取到請求都可以讀取其中的內容,很尷尬。

資料加密

為了防止請求內容被人竊取,在網路傳輸的路上我們做不了手腳,那就只能對傳輸的資料報文上做手腳了。對報文內容進行加密就是其中的一種方法。

有一種加密演算法叫做對稱加密演算法,即加密和解密使用同一個祕鑰,使用這種演算法對請求資料進行加密,中間人因為沒有祕鑰,無法讀取其中的內容。但是,使用這種演算法進行加密,肯定要同意祕鑰,那祕鑰在網路中傳輸同樣存在被竊取的風險啊。

這時,出現了新的加密演算法:非對稱加密演算法,它有兩把鑰匙,一把叫私鑰,是隻有自己知道的,另一個叫公鑰,可以發到網際網路山,隨便誰都可以看到,也就是說,傳輸過程中即使被別人看到也無所謂。這時,A向B發訊息時,可以先用B的公鑰對資料進行加密,B收到訊息後再使用自己的私鑰進行解密,中間即使被竊取了,因為沒有對應的祕鑰,也無法對了資料進行解密。

但是,非對稱加密演算法要比對稱加密演算法慢上許多。一個折中的辦法,先使用非對稱加密演算法來傳輸對稱加密的祕鑰,以確保祕鑰安全送達,之後就可以使用對稱加密演算法來加密資料報文了。

中間人劫持

你以為現在可以高枕無憂了嗎?你以為你可以放心安全的進行通訊了嗎?天真。

假設,你現在正在和A通訊,來自靈魂的拷問:你怎麼能確定和你通訊的人是A呢?

我們假設,通訊正常進行。在通訊開始傳輸公鑰的時候,請求被中間人C劫持了。C講A的公鑰換成自己的公鑰發給了你,在你傳送請求後,再講你的資訊解密,使用A的公鑰進行加密,傳送給A。這樣,在你和A看來好像是在和彼此通訊,其實所有的資訊都經過了C,所有的資訊都被C一覽無餘。

那麼如何保證收到的公鑰是A的呢?完犢子了,又回到開始的問題了,如何保證祕鑰在網路中安全的傳輸。但這次,加密似乎救不了我們了,我們必須要確保收到的祕鑰確實是A發來的,也就是說報文沒有別中途篡改過。

數字證書

其實無法保證報文內容的關鍵,在於我們對於收到的公鑰無法確定有沒有被人修改過,那如果有一個我們信任的中間人S來傳輸這個公鑰就可以了。問題來了,D的公鑰傳輸中同樣存在被修改的問題,拿到再找其他人來傳輸S的公鑰麼?這要下去簡直沒完沒了,完全就是三次握手的翻版。

問題的根源是什麼?我們沒有一個可以信任的公鑰,那麼解決辦法也很粗暴,我們在本地儲存一個絕對信任的公鑰,它不是通過網際網路來獲取的,而是預裝在系統中的,也就是系統/瀏覽器預置的頂層CA證書。

這些預裝信任的內容,就是CA證書。通過CA獲取A的公鑰時,獲得的數字證書大概長這樣:

當收到證書後,我們對資訊通過童謠的hash演算法計算出資訊摘要,在用CA的公鑰對數字簽名進行解密,若解密後的資訊摘要與我們計算的摘要相同,則可以認為資訊沒有被人修改過。驗證流程如下:

難道這樣就不拍別人篡改了麼?不怕。因為我們已經拿到CA的公鑰了,這是沒有問題的。中間人因為沒有CA的私鑰,及時擷取到資訊,也無法對修改後的內容進行加密並生成對應的數字簽名。

這樣一來,資訊的傳輸問題算是暫時告一段落了。(不知道什麼時候就冒出了新的安全問題,畢竟道高一尺魔高一丈)

HTTPS

到這裡,HTTPS介紹完畢,以上大概就是HTTPS的全部內容了。HTTPS的一次請求,大概流程如下:

  1. 瀏覽器發出HTTPS請求

  2. 伺服器講自己的數字證書返回

  3. 瀏覽器用預置的CA來驗證證書,若沒有問題,順利拿到公鑰

  4. 瀏覽器生成對稱加密演算法的祕鑰,通過伺服器的公鑰進行加密,將報文傳送給伺服器

  5. 伺服器用自己的私鑰進行解密,得到對稱加密的祕鑰

  6. 可以開始用獲得的對稱加密祕鑰進行通訊了