天天看點

SSL/TLS 協定 詳解

原文位址:https://cshihong.github.io/2019/05/09/SSL%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3/

SSL VPN可參考:SSL VPN技術原理

SSL簡介

SSL和TLS:

SSL (Secure Sockets Layer)安全套接層。是由Netscape公司于1990年開發,用于保障Word Wide Web(WWW)通訊的安全。主要任務是提供私密性,資訊完整性和身份認證。1994年改版為SSLv2,1995年改版為SSLv3.

TLS(Transport Layer Security)安全傳輸層協定,)用于在兩個通信應用程式之間提供保密性和資料完整性。該标準協定是由IETF于1999年頒布,整體來說TLS非常類似SSLv3,隻是對SSLv3做了些增加和修改。

SSL協定介紹:

SSL是一個不依賴于平台和運用程式的協定,位于TCP/IP協定與各種應用層協定之間,為資料通信提高安全支援。

圖:SSL在協定層中的位置

SSL加密知名協定:

HTTP over SSL:

簡寫https,加密網頁浏覽是設計SSL的初衷,HTTP也是第一個使用SSL保障安全的應用層協定。

​ 當Netscape在它的Navigator裡面運用HTTP over SSL的時候,使用https://來辨別HTTP over SSL,是以我常見的https的全稱就是HTTP over SSL。後來HTTPS在RFC2818被标準化。HTTPS工作在443端口,而HTTP預設工作在80端口。

Email over SSL:

類似于HTTP over SSL,郵件協定例如:

  • SMTP,POP3、IMAP也能支援SSL。
  • SMTP over TLS的标準文檔在RFC2487
  • POP3和IMAP over TLS的标準化文檔在RFC2595.

SSL原理詳解

SSL協定結構:

圖:SSL協定體系結構

SSL的體系結構中包含兩個協定子層,其中底層是SSL記錄協定層(SSL Record Protocol Layer);高層是SSL握手協定層(SSL HandShake Protocol Layer)。

SSL協定主要分為兩層:

  • SSL記錄協定層的作用是為高層協定提供基本的安全服務。SSL記錄協定針對HTTP協定進行了特别的設計,使得超文本的傳輸協定HTTP能夠在SSL運作。紀錄封裝各種高層協定,具體實施壓縮解壓縮、加密解密、計算和校驗MAC等與安全有關的操作。
  • SSL握手協定層包括SSL握手協定(SSL HandShake Protocol)、SSL密碼參數修改協定(SSL Change Cipher Spec Protocol)和SSL告警協定(SSL Alert Protocol)。握手層的這些協定用于SSL管理資訊的交換,允許應用協定傳送資料之間互相驗證,協商加密算法和生成密鑰等。

    SSL握手協定的作用是協調客戶和伺服器的狀态,使雙方能夠達到狀态的同步。

其中最重要的是記錄協定和握手協定:

  • SSL記錄協定:它建立在可靠的傳輸(如TCP)之上,為高層協定提供資料封裝、壓縮、加密等基本功能。
  • SSL握手協定:它建立在SSL記錄協定之上,用于在實際的資料傳輸開始之前,通訊雙方進行身份認證、協商加密算法、交換加密密鑰等。

SSL建立階段與IPSec VPN類比的話:

可以分為兩個大階段:

(1)SSL建立的第一階段:Handshake phase(握手階段):

  • 協商加密算法
  • 認證伺服器
  • 建立用于加密和MAC(Message Authentication Code)用的密鑰
該階段類似于IPSec VPN IKE的作用。

(2)SSL建立第二階段:Secure data transfer phase(安全的資料傳輸階段):

  • 在已經建立的SSL連接配接裡安全的傳輸資料。
該階段類似于IPSec VPN ESP的作用

SSL原理(SSL建立)握手協定總過程:

圖:SSL建立總過程

在用SSL進行通信之前,首先要使用SSL的Handshake協定在通信兩端握手,協商資料傳輸中要用到的相關安全參數(如加密算法、共享密鑰、産生密鑰所要的材料等),并對對端的身份進行驗證。

SSL的建立過程總共有13個包,第一次建立至少需要9個包。

SSL建立第一階段:

用戶端首先發送ClientHello消息到服務端,服務端收到ClientHello消息後,再發送ServerHello消息回應用戶端。

SSL/TLS 協定 詳解

圖:SSL建立第一階段封包交換示意圖

ClientHello

握手第一步是用戶端向服務端發送 Client Hello 消息,這個消息裡包含了一個用戶端生成的随機數 Random1、用戶端支援的加密套件(Support Ciphers)和 SSL Version 等資訊。

SSL/TLS 協定 詳解

圖:ClinetHello封包抓包示例

ClientHello中涉及到的消息具體如下:

  • 用戶端版本

    按優先級列出用戶端支援的協定版本,首選用戶端希望支援的最新協定版本。

  • 用戶端随機數Random
  • 會話ID(Session id)

    如果用戶端第一次連接配接到伺服器,那麼這個字段就會保持為空。上圖中該字段為空,說明這是第一次連接配接到伺服器。

    如果該字段不為空,說明以前是與伺服器有連接配接的,在此期間,伺服器将使用Session ID映射對稱密鑰,并将Session ID存儲在用戶端浏覽器中,為映射設定一個時間限。如果浏覽器将來連接配接到同一台伺服器(在時間到期之前),它将發送Session ID,伺服器将對映射的Session ID進行驗證,并使用以前用過的對稱密鑰來恢複Session,這種情況下不需要完全握手。也叫作SSL會話恢複。後面會有介紹。

  • 加密套件:

    用戶端會給伺服器發送自己已經知道的密碼套件清單,這是由客戶按優先級排列的,但完全由伺服器來決定發送與否。TLS中使用的密碼套件有一種标準格式。上面的封包中,用戶端發送了74套加密套件。服務端會從中選出一種來作為雙方共同的加密套件。

  • 壓縮方法:

    為了減少帶寬,可以進行壓縮。但從成功攻擊TLS的事例中來看,其中使用壓縮時的攻擊可以捕獲到用HTTP頭發送的參數,這個攻擊可以劫持Cookie,這個漏洞我們稱為CRIME。從TLS 1.3開始,協定就禁用了TLS壓縮。

  • 擴充包:

    其他參數(如伺服器名稱,填充,支援的簽名算法等)可以作為擴充名使用。

    這些是用戶端問候的一部分,如果已收到用戶端問候,接下來就是伺服器的确認,伺服器将發送伺服器問候。

ServerHello

收到用戶端問候之後伺服器必須發送伺服器問候資訊,伺服器會檢查指定諸如TLS版本和算法的用戶端問候的條件,如果伺服器接受并支援所有條件,它将發送其證書以及其他詳細資訊,否則,伺服器将發送握手失敗消息。

如果接受,第二步是服務端向用戶端發送 Server Hello 消息,這個消息會從 Client Hello 傳過來的 Support Ciphers 裡确定一份加密套件,這個套件決定了後續加密和生成摘要時具體使用哪些算法,另外還會生成一份随機數 Random2。注意,至此用戶端和服務端都擁有了兩個随機數(Random1+ Random2),這兩個随機數會在後續生成對稱秘鑰時用到。

SSL/TLS 協定 詳解

圖:ServerHello封包抓包

ServerHello中涉及到的具體參數:

  • 伺服器版本Version:

    伺服器會選擇用戶端支援的最新版本。

  • 伺服器随機數Random:

    伺服器和用戶端都會生成32位元組的随機數。用來建立加密密鑰。

  • 伺服器會從用戶端發送的加密套件清單中選出一個加密套件。
  • 會話ID(Session ID):

     伺服器将約定的Session參數存儲在TLS緩存中,并生成與其對應的Session id。它與Server Hello一起發送到用戶端。用戶端可以寫入約定的參數到此Session id,并給定到期時間。用戶端将在Client Hello中包含此id。如果用戶端在此到期時間之前再次連接配接到伺服器,則伺服器可以檢查與Session id對應的緩存參數,并重用它們而無需完全握手。這非常有用,因為伺服器和用戶端都可以節省大量的計算成本。

      在涉及亞馬遜和谷歌等流量巨大的應用程式時,這種方法存在缺點。每天都有數百萬人連接配接到伺服器,伺服器必須使用Session密鑰保留所有Session參數的TLS緩存。這是一個巨大的開銷。

    為了解決這個問題,在擴充包裡加入了Session Tickets, 在這裡,用戶端可以在client hello中指定它是否支援Session Ticket。然後,伺服器将建立一個新的會話票證(Session Ticket),并使用隻有伺服器知道的經過私鑰加密的Session參數。它将存儲在用戶端上,是以所有Session資料僅存儲在用戶端計算機上,但Ticket仍然是安全的,因為該密鑰隻有伺服器知道。

      此資料可以作為名為Session Ticket的擴充包含在Client Hello中。

  • 壓縮算法:

    如果支援,伺服器将同意用戶端的首選壓縮方法。

  • 擴充包

這個階段之後,用戶端服務端知道了下列内容:

  1. SSL版本
  2. 密鑰交換、資訊驗證和加密算法
  3. 壓縮方法
  4. 有關密鑰生成的兩個随機數。

SSL建立第二階段:

伺服器向用戶端發送消息。

SSL/TLS 協定 詳解

圖:SSL建立第二階段封包交換示意圖

伺服器啟動SSL握手第2階段,是本階段所有消息的唯一發送方,客戶機是所有消息的唯一接收方。該階段分為4步:

  1. 證書:伺服器将數字證書和到根CA整個鍊發給用戶端,使用戶端能用伺服器證書中的伺服器公鑰認證伺服器。
  2. 伺服器密鑰交換(可選):這裡視密鑰交換算法而定
  3. 證書請求:服務端可能會要求客戶自身進行驗證。
  4. 伺服器握手完成:第二階段的結束,第三階段開始的信号

Certificate消息(可選)—第一次建立必須要有證書

一般情況下,除了會話恢複時不需要發送該消息,在SSL握手的全流程中,都需要包含該消息。消息包含一個X.509證書,證書中包含公鑰,發給用戶端用來驗證簽名或在密鑰交換的時候給消息加密。

這一步是服務端将自己的證書下發給用戶端,讓用戶端驗證自己的身份,用戶端驗證通過後取出證書中的公鑰。

SSL/TLS 協定 詳解

圖:伺服器給用戶端發送的證書封包

Server Key Exchange(可選)

根據之前在ClientHello消息中包含的CipherSuite資訊,決定了密鑰交換方式(例如RSA或者DH),是以在Server Key Exchange消息中便會包含完成密鑰交換所需的一系列參數。

圖:Server Key Exchange封包

因為這裡是DH算法,是以需要發送伺服器使用的DH參數。RSA算法不需要這一步。

在Diffie-Hellman中,用戶端無法自行計算預主密鑰; 雙方都有助于計算它,是以用戶端需要從伺服器擷取Diffie-Hellman公鑰。

由上圖可知,此時密鑰交換也由簽名保護。

Certificate Request(可選)——可以是單向的身份認證,也可以雙向認證

這一步是可選的,如果在對安全性要求高的常見可能用到。伺服器用來驗證用戶端。伺服器端發出Certificate Request消息,要求用戶端發他自己的證書過來進行驗證。該消息中包含伺服器端支援的證書類型(RSA、DSA、ECDSA等)和伺服器端所信任的所有證書發行機構的CA清單,用戶端會用這些資訊來篩選證書。

Server Hello Done

該消息表示伺服器已經将所有資訊發送完畢,接下來等待用戶端的消息。

SSL/TLS 協定 詳解

圖;Server Hello Done封包

SSL建立第三階段:

用戶端收到伺服器發送的一系列消息并解析後,将本端相應的消息發送給伺服器。

SSL/TLS 協定 詳解

圖:SSL建立第三階段封包交換示意圖

客戶機啟動SSL握手第3階段,是本階段所有消息的唯一發送方,伺服器是所有消息的唯一接收方。該階段分為3步:

  1. 證書(可選):為了對伺服器證明自身,客戶要發送一個證書資訊,這是可選的,在IIS中可以配置強制用戶端證書認證。
  2. 客戶機密鑰交換(Pre-master-secret):這裡用戶端将預備主密鑰發送給服務端,注意這裡會使用服務端的公鑰進行加密。
  3. 證書驗證(可選),對預備秘密和随機數進行簽名,證明擁有(a)證書的公鑰。

Certificate(可選)

如果在第二階段伺服器端要求發送用戶端證書,用戶端便會在該階段将自己的證書發送過去。伺服器端在之前發送的Certificate Request消息中包含了伺服器端所支援的證書類型和CA清單,是以用戶端會在自己的證書中選擇滿足這兩個條件的第一個證書發送過去。若用戶端沒有證書,則發送一個no_certificate警告。

Client Key exchange

根據之前從伺服器端收到的随機數,按照不同的密鑰交換算法,算出一個pre-master,發送給伺服器,伺服器端收到pre-master算出main master。而用戶端當然也能自己通過pre-master算出main master。如此以來雙方就算出了對稱密鑰。

如果是RSA算法,會生成一個48位元組的随機數,然後用server的公鑰加密後再放入封包中。如果是DH算法,這是發送的就是用戶端的DH參數,之後伺服器和用戶端根據DH算法,各自計算出相同的pre-master secret.

SSL/TLS 協定 詳解

圖:Clinet Key exchange封包

本消息在給伺服器發送的過程中,使用了伺服器的公鑰加密。伺服器用自己的私鑰解密後才能得到pre-master key.(向伺服器證明自己的确持有用戶端證書私鑰。)

Certificate verify(可選)

隻有在用戶端發送了自己證書到伺服器端,這個消息才需要發送。其中包含一個簽名,對從第一條消息以來的所有握手消息的HMAC值(用master_secret)進行簽名。

SSL建立第四階段:

完成握手協定,建立SSL連接配接。

SSL/TLS 協定 詳解

圖:SSL建立第四階段封包交換示意圖

客戶機啟動SSL握手第4階段,使伺服器結束。該階段分為4步,前2個消息來自客戶機,後2個消息來自伺服器。

建立起一個安全的連接配接,用戶端發送一個Change Cipher Spec消息,并且把協商得到的CipherSuite拷貝到目前連接配接的狀态之中。然後,用戶端用新的算法、密鑰參數發送一個Finished消息,這條消息可以檢查密鑰交換和認證過程是否已經成功。其中包括一個校驗值,對用戶端整個握手過程的消息進行校驗。伺服器同樣發送Change Cipher Spec消息和Finished消息。握手過程完成,用戶端和伺服器可以交換應用層資料進行通信。

ChangeCipherSpec :

編碼改變通知,表示随後的資訊都将用雙方商定的加密方法和密鑰發送(ChangeCipherSpec是一個獨立的協定,展現在資料包中就是一個位元組的資料,用于告知服務端,用戶端已經切換到之前協商好的加密套件(Cipher Suite)的狀态,準備使用之前協商好的加密套件加密資料并傳輸了)。

SSL/TLS 協定 詳解

圖:Cipher Spec Message封包

是一條事件消息。

Clinet Finished:

用戶端握手結束通知, 表示用戶端的握手階段已經結束。這一項同時也是前面發送的所有内容的hash值,用來供伺服器校驗(使用HMAC算法計算收到和發送的所有握手消息的摘要,然後通過RFC5246中定義的一個僞函數PRF計算出結果,加密後發送。此資料是為了在正式傳輸應用資料之前對剛剛握手建立起來的加解密通道進行驗證。)

Server Finished:

服務端握手結束通知。

  1. 使用私鑰解密加密的Pre-master資料,基于之前(Client Hello 和 Server Hello)交換的兩個明文随機數 random_C 和 random_S,計算得到協商密鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
  2. 計算之前所有接收資訊的 hash 值,然後解密用戶端發送的 encrypted_handshake_message,驗證資料和密鑰正确性;
  3. 發送一個 ChangeCipherSpec(告知用戶端已經切換到協商過的加密套件狀态,準備使用加密套件和 Session Secret加密資料了)
  4. 服務端也會使用 Session Secret 加密一段 Finish 消息發送給用戶端,以驗證之前通過握手建立起來的加解密通道是否成功。

根據之前的握手資訊,如果用戶端和服務端都能對Finish資訊進行正常加解密且消息正确的被驗證,則說明握手通道已經建立成功,接下來,雙方可以使用上面産生的Session Secret對資料進行加密傳輸了。

消息驗證代碼(HMAC)和TLS資料完整性:

當伺服器或用戶端使用主密鑰加密資料時,它還會計算明文資料的校驗和(哈希值),這個校驗和稱為消息驗證代碼(MAC)。然後在發送之前将MAC包含在加密資料中。密鑰用于從資料中生成MAC,以確定傳輸過程中攻擊者無法從資料中生成相同的MAC,故而MAC被稱為HMAC(哈希消息認證碼)。另一方面,在接收到消息時,解密器将MAC與明文分開,然後用它的密鑰計算明文的校驗和,并将其與接收到的MAC進行比較,如果比對,那我們就可以得出結論:資料在傳輸過程中沒有被篡改。

幾個重要的secret key:

PreMaster secret

PreMaster Secret是在用戶端使用RSA或者Diffie-Hellman等加密算法生成的。它将用來跟服務端和用戶端在Hello階段産生的随機數結合在一起生成 Master Secret。PreMaster secret前兩個位元組是TLS的版本号,這是一個比較重要的用來核對握手資料的版本号。服務端需要對密文中解密出來對的PreMaster版本号跟之前Client Hello階段的版本号進行對比,如果版本号變低,則說明被串改,則立即停止發送任何消息。

Master secret

由于最後通過交換,用戶端和服務端都會有Pre-master和随機數,這個随機數将作為後面産生Master secret的種子,結合PreMaster secret,用戶端和服務端将計算出同樣的Master secret。

SSL/TLS 協定 詳解

為了保證資訊的完整性和機密性,SSL需要有六個加密密鑰:四個密鑰和兩個IV。為了資訊的可信性,用戶端需要一個密鑰(HMAC),為了加密要有一個密鑰,為了分組加密要一個IV,伺服器也是如此。SSL需要的密鑰是單向的,不同于那些在其他方向的密鑰。如果在一個方向上有攻擊,這種攻擊在其他方向是沒影響的。生成過程如下:

SSL/TLS 協定 詳解

主密鑰是由一系列的Hash值組成。

複制
1
2
      
> master_secret = PRF(pre_master_secret,“master secret”,ClientHello.random + ServerHello.random)[0..47];
>
      
SSL/TLS 協定 詳解
SSL/TLS 協定 詳解

 根據要求,有4個密鑰用于加密和驗證每個消息的完整性,他們是:

  • 用戶端寫入加密密鑰:用戶端用來加密資料,伺服器用來解密資料。
  • 伺服器寫入加密密鑰:伺服器用來加密資料,用戶端用來解密資料。
  • 用戶端寫入MAC密鑰:用戶端用來建立MAC,伺服器用來驗證MAC。
  • 伺服器寫入MAC密鑰:伺服器用來建立MAC,用戶端用來驗證MAC。

SSL會話恢複:

會話恢複是指隻要用戶端和伺服器已經通信過一次,它們就可以通過會話恢複的方式來跳過整個握手階段二直接進行資料傳輸。

SSL/TLS 協定 詳解

圖:SSL會話恢複過程

SSL采用會話恢複的方式來減少SSL握手過程中造成的巨大開銷。

為了加快建立握手的速度,減少協定帶來的性能降低和資源消耗(具體分析在後文),TLS 協定有兩類會話緩存機制:

  • 會話辨別 session ID: 由伺服器端支援,協定中的标準字段,是以基本所有伺服器都支援,伺服器端儲存會話ID以及協商的通信資訊,Nginx 中1M 記憶體約可以儲存4000個 session ID 機器相關資訊,占用伺服器資源較多;
  • 會話記錄 session ticket :t需要伺服器和用戶端都支援,屬于一個擴充字段,支援範圍約60%(無可靠統計與來源),将協商的通信資訊加密之後發送給用戶端儲存,密鑰隻有伺服器知道,占用伺服器資源很少。
  • 二者對比,主要是儲存協商資訊的位置與方式不同,類似與 http 中的 session 與 cookie。二者都存在的情況下,(nginx 實作)優先使用 session_ticket。

會話恢複具體過程(Session ID機制):

  1. 如果用戶端和伺服器之間曾經建立了連接配接,伺服器會在握手成功後傳回 session ID,并儲存對應的通信參數在伺服器中;
  2. 如果用戶端再次需要和該伺服器建立連接配接,則在 client_hello 中 session ID 中攜帶記錄的資訊,發送給伺服器;
  3. 伺服器根據收到的 session ID 檢索緩存記錄,如果沒有檢索到貨緩存過期,則按照正常的握手過程進行;
  4. 如果檢索到對應的緩存記錄,則傳回 change_cipher_spec 與 encrypted_handshake_message 資訊,兩個資訊作用類似,encrypted_handshake_message 是到目前的通信參數與 master_secret的hash 值;
  5. 如果用戶端能夠驗證通過伺服器加密資料,則用戶端同樣發送 change_cipher_spec 與 encrypted_handshake_message 資訊;
  6. 伺服器驗證資料通過,則握手建立成功,開始進行正常的加密資料通信。

會話恢複具體過程( session ticket):

  1. 如果用戶端和伺服器之間曾經建立了連接配接,伺服器會在 new_session_ticket 資料中攜帶加密的 session_ticket 資訊,用戶端儲存;
  2. 如果用戶端再次需要和該伺服器建立連接配接,則在 client_hello 中擴充字段 session_ticket 中攜帶加密資訊,一起發送給伺服器;
  3. 伺服器解密 sesssion_ticket 資料,如果能夠解密失敗,則按照正常的握手過程進行;
  4. 如果解密成功,則傳回 change_cipher_spec 與 encrypted_handshake_message 資訊,兩個資訊作用與 session ID 中類似;
  5. 如果用戶端能夠驗證通過伺服器加密資料,則用戶端同樣發送 change_cipher_spec與encrypted_handshake_message 資訊;

SSL記錄協定:

SSL記錄協定主要用來實作對資料塊的分塊、加密解密、壓縮與解壓縮、完整性檢查及封裝各種高層協定。

SSL/TLS 協定 詳解

圖:SSL記錄協定結構

每個SSL記錄主要包含以下資訊:

  • 内容類型
  • 協定版本号,目前有2.0和3.0版本
  • 記錄資料的長度
  • 資料由載荷
  • 雜湊演算法計算消息認證代碼
SSL/TLS 協定 詳解

圖:SSL記錄協定工作原理

  • 将消息分割為多個片段;
  • 對每個片段進行壓縮
  • 加上片段編号(防止重播攻擊)計算消息驗證碼MAC值(保證資料完整性),追加在壓縮片段
  • 對稱密碼加密;
  • 加上資料類型、版本号、壓縮後的長度組成的報頭, 就是最終的封包資料;

應用資料傳輸:

在所有的握手階段都完成之後,就可以開始傳送應用資料了。應用資料在傳輸之前,首先要附加上MAC secret,然後再對這個資料包使用write encryption key進行加密。在服務端收到密文之後,使用Client write encryption key進行解密,用戶端收到服務端的資料之後使用Server write encryption key進行解密,然後使用各自的write MAC key對資料的完整性包括是否被串改進行驗證。

首先明确一個概念:非對稱加密算法

非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對資料進行加密,隻有用對應的私有密鑰才能解密;如果用私有密鑰對資料進行加密,那麼隻有用對應的公開密鑰才能解密。

HTTPS協定中,前面的握手過程,伺服器會将公鑰發給用戶端,用戶端驗證後生成一個密鑰用公鑰加密後發送給伺服器,成功後建立通信。

通信過程用戶端将請求資料用得到的公鑰加密後,發給伺服器,伺服器用私鑰解密。伺服器用用戶端給的密鑰加密響應封包,發回給用戶端,用戶端用自己存的密鑰解密。

忽略掉其他例如确定協定和版本号之類的環節,提煉出來的重要環節如下:

SSL/TLS 協定 詳解

公私玥A用于非對稱式加密,密鑰B隻用于普通的對稱式加密。

簡而言之就是這樣,那麼問題來了:你作為一個中間人,你沒有伺服器私鑰A,是不能解密用戶端發送的内容的,如果你沒有用戶端自己生成的密鑰B,是以你也不能解密用戶端發過去的内容的。

請注意:這兩個私鑰都是兩端各自儲存,而私鑰A是隻儲存在伺服器上,從不對外發送的。

SSL/TLS 協定 詳解

結果就是,你收發的資料,他都能看到——————但是他不能解密,看不懂。

這隻是最普通的劫持HTTP的方式,HTTPS就是為了解決題主所說的這個中間人攻擊而産生的,然而題主并沒有去了解HTTPS的工作原理,而用HTTP的原始思路繼續去思考HTTPS,是以題主這個方法是完全不可行的。

繼續往下想,或許有人會覺得:

如果你自己簽發一對非對稱式公私鑰C,還有密鑰D,然後作為一個中間人。在一開始的通信環節,用公私鑰C替代公私鑰A,用密鑰D替代密鑰B。這樣分發給對應的伺服器和用戶端,這樣他們發給自己的資訊,自己都能解密。然後自己再用真正的公鑰A把解密後的資訊重新加密發給伺服器騙取響應封包,把響應封包用密鑰B(前面用戶端用公鑰C加密後,被中間人用私鑰C解密的刀)重新加密發回給用戶端騙取新的請求封包。

這樣豈不是可以瞞天過海?

那麼在圖中所示的驗證環節,因為你的證書是自己簽發的,是以證書跟指紋拿去去系統裡可信頒發機構的證書那一對,肯定對不上。

SSL/TLS 協定 詳解

例如我用Fiddler給自己簽發了個證書,因為頒發者不在系統受信任證書頒發機構裡,會直接報警:

SSL/TLS 協定 詳解

如果你要假冒其他機構頒發證書,因為你沒有頒發機構的密鑰,那麼你頒發的證書,結果指紋肯定沒辦法對上,還是一樣會報警。

SSL/TLS 協定 詳解

系統信任的頒發機構一般都是權威的大機構,當然你也可以自己導入自己信任的機構的證書,用來驗證簽名。

SSL/TLS 協定 詳解

如果要實作HTTPS下的中間人攻擊,你應該讓自己的根證書進入系統裡,讓自己成為裁判。

這是HTTPS中間人攻擊中最難也是最簡單的一點——畢竟使用者很好騙。

SSL/TLS 協定 詳解

你可以這麼做,或者跟上一張圖證書中的第三第四行所示的那麼做。

還有人就說了,我可以讓使用者回落到HTTP協定啊,中間人用HTTPS跟伺服器通信,然後用HTTP跟用戶端通信——要知道大部分使用者在位址欄輸入URL時,并沒有指定協定的習慣,都是打www開頭而不是打https://開頭,能用HTTPS全是Web Server上80端口301 Location到HTTPS的功勞。

看起來似乎中間人充當了一個替換頁面裡HTTPS資源到HTTP的反向代理,好像可行性還是很高。

但是隻要利用HSTS(HTTP Strict Transport Security,RFC6797)就可以解決這個問題。通過在HTTP Header中加入Strict-Transport-Security的聲明,告訴浏覽器在一定時間内必須通過HTTPS協定通路本域名下的資源。

這種情況下,隻要使用者曾經在安全網絡環境下通路過一次某站,中間人在指定時間内也無法讓其回落到HTTP。

原文位址:https://www.zhihu.com/question/22795329

SSL/TLS 協定 詳解

如果這篇文章幫助到了你,你可以請作者喝一杯咖啡

SSL/TLS 協定 詳解