TLS/SSL創建在應用層和傳輸層TCP之間,將到達TCP前的數據都進行加密處理,前面作了那麼多的工做,握手密鑰協商,數字簽名防抵賴等,都是爲了保證數據的完整性和機密性。HTTP結合TLS/SSL協議就是HTTPS,若是HTTP消息不交由TLS/SSL協議,一旦流量被截獲了,最大的問題就是隱私泄露, 若是咱們在一個沒有部署HTTPS的網站上登錄咱們的信息,以HTTP流量方式進行發送,因爲明文傳輸的緣由,一旦請求被截獲,裏面的內容就泄露了。路由選擇讓這些報文分組通過不少節點設備,在這些節點路由中等待分組轉發的報文都有可能被截獲而後篡改,雖然TCP可以保證數據正確到達通訊雙方處,但不能保證數據是正確的沒有被篡改的,對於沒有使用TLS/SSL的服務器來講,只要收到的HTTP請求格式是正確的,就會給予響應。像下面這樣狀況:git
若是咱們在一個HTTP頁面傳輸數據,例如在一個登錄頁面,輸入本身的用戶名和密碼併發送給服務器,中途流量被截獲了,直接泄露了咱們發送的數據,像上圖同樣。而若是咱們在部署了HTTPS的網站上登錄,由於數據在到達TCP前就交由TLS/SSL協議進行加密,以後再發送,因此中間流量被截獲後,看到的也是通過加密的密文:算法
能夠看到,用戶名和密碼都是一串亂碼。拿DH密鑰協商舉例,客戶端和服務器端通過密鑰協商後獲得對方的公鑰,使用公鑰加密後的密文僅對方的私鑰能夠解出明文,因此即便在流量發送過程當中被截獲了,也能保證數據不泄露。瀏覽器
除了數據未加密的問題外,身份校驗也是一個問題,在部署了HTTPS的網站中,CA機構會爲其簽發一張證書,證書裏面包含了一些服務器的關鍵信息,例如服務器公鑰,主機名等,CA機構用本身的RSA私鑰對該證書進行簽名,瀏覽器由於對CA機構的信任,一般內嵌CA機構的公鑰,在身份校驗時,服務器向客戶端發送本身的證書,瀏覽器使用CA公鑰驗證證書籤名,成功後,便可使用裏面的服務器公鑰進行密鑰協商。服務器
TLS/SSL協議作的東西不少,前面的日誌裏也總結了大體的步驟,還有各個子協議,子消息和擴展項,接下來抓一下HTTPS流量,看看一個網址從創建鏈接開始,到會話恢復等各部份內容,分析下整個TLS的處理過程。session
首先打開一個HTTPS網頁,就拿CSDN首頁爲例吧,打開網站後,咱們抓取過程當中的HTTPS流量,看看使用TLS協議的網站在客戶端(瀏覽器)和服務器端創建鏈接過程當中發送交換的各個子消息:併發
能夠看到,咱們訪問一個HTTPS網站時,使用了TLS v1.2版本協議,經歷了握手協議過程,dom
一、 首先由客戶端發送Client Hello子消息,而後服務器端迴應ServerHello。網站
二、 接着由服務器(注意看前面,服務器ip爲47.95.47.253)發送證書Certificate,Certificate Status擴展供證書吊銷狀態校驗,Server Key Exchange子消息表示進行密鑰協商的一部分,例如使用DH密鑰協商,服務器須要向客戶端發送本身的DH參數和DH公鑰,因此經過該子消息來傳遞。最後發送Server Hello Done。加密
三、 客戶端在收到Server Hello Done後,迴應Client Key Exchange進行密鑰協商(例如根據服務器發來的DH參數生成客戶端DH密鑰對,而後經過Client Key Exchange子消息把客戶端公鑰發送給服務器端,完成密鑰協商),Change Cipher Spec子消息表示TLS記錄層須要的加密參數都準備好,能夠切換鏈接狀態爲可讀和可寫狀態。最後的Encrypted Handshake Message子消息就是Finished子消息,用來校驗握手消息沒有被篡改。.net
四、 最後是由服務器發送Change Cipher Spec和Encrypted Handshake Message,注意上圖中服務器還發送了New Session Ticket,代表了本次會話可使用Session Ticket方式進行會話恢復。待服務器發送完Finished子消息後,接下來的應用層數據均可以進行加密處理了。
按照前面咱們說過的,Client Hello子消息中包含有客戶端支持的密碼套件(用於協商),擴展項等,下面查看下Client Hello子消息裏的詳細內容:
能夠看到,最上面Record Layer:Handshake Protocol,由TLS記錄層進行了封裝握手協議,握手協議中發送的子消息是Client Hello,裏面是客戶端支持的最高TLS版本號v1.2,隨機數Random,Session ID和支持的密碼套件,能夠看到支持的媽咪套件由17個,優先支持的是TLS_AES_128_GCM_SHA256(0x1301)。
往下看還有客戶端的擴展項,server_name表示客戶端使用了SNI服務器名稱指示擴展,告訴服務器請求訪問的主機名,讓服務器發送相應的證書供校驗。session_ticket擴展就是告訴服務器請求使用SessionTicket方式進行會話恢復,第一次創建完整TLS握手時,客戶端發送的該擴展是空的,由服務器決定是否支持SessionTicket。status_request擴展也是之前總結過,若是校驗證書吊銷狀態方式使用OCSP在線證書狀態協議,那麼就是發送該擴展,若是使用OCSP套封,即由服務器來發送OCSP請求,獲取響應後,服務器再向客戶端發送CertificateStaus子消息,裏面包含了證書吊銷狀態信息。還有一個signed_certificate_timestamp擴展表示支持證書透明度機制,由CA機構或服務器實體提交,Certificate Logs返回一個SCT信息,至關於也是一個票據,客戶端再TLS/SSL協議握手階段獲取該SCT信息,證實該證書是通過監控和審計的。
接下來看服務器端迴應的Server Hello:
能夠看到,常規的TLS版本號,隨機數信息,值得注意的是Session ID爲0,代表在本次握手中,服務器端選擇了不使用Session ID進行會話恢復,從上面Client Hello和Server Hello中都看到空的session_ticket擴展項,代表服務器端支持也選擇使用SessionTicket進行會話恢復,因此棄用了Session ID。
往下走,由服務器端發送Certificate證書供客戶端進行校驗,從證書信息中咱們能夠看到,除了服務器實體證書外,還有一箇中間證書:
第一個證書是咱們的服務器實體證書,也就是CSDN的服務器,commonName=*.csdn.net。證書版本v3,序列號信息,還有使用的證書籤名算法爲sha256WithRSA。下面的validity標識證書的有效期,從2018-11-07到2020-11-06,還有一個值得注意的重要信息是服務器公鑰,subjectPublicKey。第二個證書是中間證書,由GeoTrust RSA CA機構簽發,詳細信息就不展現出來了,有興趣的你們能夠去抓抓CSDN的首頁來看便可。
證書中還要注意的是證書擴展項,裏面有不少內容,標識該證書的做用,拿服務器實體證書爲例,看看裏面的擴展項都有哪些:
證書中有10個擴展項,authorityKeyIdentifier是CA密鑰標識符,subjectKeyIdentifier則是使用者密鑰標識符,subjectAltName擴展標識了服務器主機名。keyUsage擴展項比較重要,標識該證書的功能,例如digitalSignature:True表示能夠進行數字簽名,還有extKeyUsage擴展項,用來表示證書的使用場合,紅筆圈起部分能夠看到該證書能夠用來進行服務器端身份校驗和客戶端身份校驗。
authorityInfoAccess擴展裏寫有OCSP服務的地址和證書地址,basicConstraints基礎約束擴展表示該證書是一張普通證書,不能使用其來簽發其餘證書。
使用DH密鑰協商方式,服務器端發送DH參數和公鑰給客戶端,因此須要Server Key Exchange子消息:
能夠看到ECDH(EC Diffie-Hellman)參數服務器公鑰Pubkey,Signature簽名值是服務器端對該DH參數進行簽名。
客戶端收到服務器發送的DH參數和公鑰後,使用DH參數生成本身的密鑰對,保留私鑰,把公鑰經過Client Key Exchange發送給服務器端,完成密鑰協商:
Change Cipher Spec子消息很簡單,做用是告訴服務器端,客戶端須要的加密參數都準備好了,客戶端的TLS記錄層協議能夠對數據進行加密了,將鏈接狀態由待讀狀態和待寫狀態切換爲可讀狀態與可寫狀態:
本身的密鑰塊準備好,發送了Change Cipher Spec後,再給對方發送Finished供校驗全部的握手消息是沒有被篡改的:
上爲客戶端發送,下爲服務器端發送。
前面說過會話恢復有兩種方式,Session ID和Session Ticket兩種,這裏我以經常使用的Session Ticket方式爲例,抓包一下HTTPS流量,看看這Session Ticket恢復方式過程當中都發送了哪些子消息。
我抓的是簡書網站的HTTPS流量,看看第一次創建完整TLS握手的過程:
能夠看到,第一次完整的TL握手,Client Hello和Server Hello(若是服務器支持)子消息中都會帶有空的session_ticket擴展項,服務器端最後會發送New Session Ticket子消息,裏面保存了本次會話的一些信息:
例如票據的有效期Lifetime爲300秒,即5分鐘,服務器端對票據的加密值也在裏面。接下來咱們關閉簡書網頁,再從新打開,看看它是否經過Session Ticket方式進行會話恢復: