SSL/TLS協議交互流程分析


本文參考

SSL/TLS協議運行機制的概述

tls運行機制,這里不細說,建議細看

HTTPS與TLS

The Transport Layer Security (TLS) Protocol v1.2

ssl/tls基礎介紹

SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是為網絡通信提供安全及數據完整性的一種安全協議。TLS與SSL在傳輸層對網絡連接進行加密。

1. 認證用戶和服務器,確保數據發送到正確的客戶機和服務器。

2. 加密數據以防止數據中途被竊取。

3. 維護數據的完整性,確保數據在傳輸過程中不被改變。
  • 1. 認證用戶和服務器,確保數據發送到正確的客戶機和服務器。
    
    2. 加密數據以防止數據中途被竊取。
    
    3. 維護數據的完整性,確保數據在傳輸過程中不被改變。

     

ssl協議結構體

ssl協議結構

SSL位於應用層和傳輸層之間,它可以為任何基於TCP等可靠連接的應用層協議提供安全性保證。

1. SSL握手協議:是SSL協議非常重要的組成部分,用來協商通信過程中使用的加密套件(加密算法、密鑰交換算法和MAC算法等)、在服務器和客戶端之間安全地交換密鑰、實現服務器和客戶端的身份驗證。

2. SSL密碼變化協議:客戶端和服務器端通過密碼變化協議通知對端,隨后的報文都將使用新協商的加密套件和密鑰進行保護和傳輸。

3. SSL警告協議:用來向通信對端報告告警信息,消息中包含告警的嚴重級別和描述。

4. SSL記錄協議:主要負責對上層的數據(SSL握手協議、SSL密碼變化協議、SSL警告協議和應用層協議報文)進行分塊、計算並添加MAC值、加密,並把處理后的記錄塊傳輸給對端
  • 1. SSL握手協議:是SSL協議非常重要的組成部分,用來協商通信過程中使用的加密套件(加密算法、密鑰交換算法和MAC算法等)、在服務器和客戶端之間安全地交換密鑰、實現服務器和客戶端的身份驗證。
    
    2. SSL密碼變化協議:客戶端和服務器端通過密碼變化協議通知對端,隨后的報文都將使用新協商的加密套件和密鑰進行保護和傳輸。
    
    3. SSL警告協議:用來向通信對端報告告警信息,消息中包含告警的嚴重級別和描述。
    
    4. SSL記錄協議:主要負責對上層的數據(SSL握手協議、SSL密碼變化協議、SSL警告協議和應用層協議報文)進行分塊、計算並添加MAC值、加密,並把處理后的記錄塊傳輸給對端

     

加密算法

1. 散列(Hash)
把任意大小的文檔變成一個 固定大小(MD5是32個字符)的字符串,過程不可逆。MD5,SHA1等。

2. 對稱加密(Symmetric Cryptography)
使用同一個密鑰加密和解密,優點是速度快,缺點是密鑰管理不方便,要求共享密鑰。 DES,AES等。

3. 非對稱加密(Asymmetric Cryptography)
使用公鑰和私鑰來加密和解密,優點是密鑰管理很方便,缺點是速度慢。RSA,DSA等。

4. 數字簽名(Digital Signature)
使用散列和非對稱加密驗證文檔的真實性。先為要簽名的信息生成一個Hash字串,Hash1,然后用你的私鑰加密得到Encrypted(Hash1),這就是你對這個文檔的數字簽名。
當別人需要驗證某個文檔是否是你簽名的時候,只需要用你的公鑰解密你的簽名得到Hash1,並和該文檔計算出來的Hash2對比,查看是否一致。如果一致則說明你確實對該文檔簽過名,否則就是沒有。

 

 

認證方式

單向認證

客戶端向服務器發送消息,服務器接到消息后,用服務器端的密鑰庫中的私鑰對數據進行加密,然后把加密后的數據和服務器端的公鑰一起發送到客戶端,客戶端用服務器發送來的公鑰對數據解密,然后在用傳到客戶端的服務器公鑰對數據加密傳給服務器端,服務器用私鑰對數據進行解密,這就完成了客戶端和服務器之間通信的安全問題,但是單向認證沒有驗證客戶端的合法性。

雙向認證

(1)客戶端向服務器發送消息,首先把消息用客戶端證書加密然后連同時把客戶端證書一起發送到服務器端

(2)服務器接到消息后用首先用客戶端證書把消息解密,然后用服務器私鑰把消息加密,把服務器證書和消息一起發送到客戶端

(3)客戶端用發來的服務器證書對消息進行解密,然后用服務器的證書對消息加密,然后在用客戶端的證書對消息在進行一次加密,連同加密消息和客戶端證書一起發送到服務器端,

(4)到服務器端首先用客戶端傳來的證書對消息進行解密,確保消息是這個客戶發來的,然后用服務器端的私鑰對消息在進行解密這個便得到了明文數據。

一、下圖為客戶端和服務端的通信流程

雙向通信交互流程

圖中包括服務端和客戶端電子證書請求認證,下面我們分析的例子不包含請求客戶端證書認證

二、后台程序https tls/1.2驗證測試

下面為程序中的客戶端和服務端具體交互信息。通過curl命令訪問api接口:

root@sdn112:~# curl -1 --tlsv1.2 --cacert /root/ca.crt -X 'GET'  -v https://192.168.30.145:9131/v2.0/networks | python -mjson.tool
* Hostname was NOT found in DNS cache
*   Trying 192.168.30.145...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 192.168.30.145 (192.168.30.145) port 9131 (#0)
* successfully set certificate verify locations:
*   CAfile: /root/ca.crt
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]
* SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
* SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Finished (20):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
* SSLv3, TLS handshake, Finished (20):
{ [data not shown]
* SSL connection using ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*    subject: C=cn; ST=hb; O=fiberhome; OU=fitos; CN=192.168.30.145
*    start date: 2017-09-21 09:29:38 GMT
*    expire date: 2018-09-21 09:29:38 GMT
*    common name: 192.168.30.145 (matched)
*    issuer: C=cn; ST=hb; L=wh; O=fiberhome; OU=fitos; CN=192.168.30.145
*    SSL certificate verify ok.
> GET /v2.0/networks HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 192.168.30.145:9131
> Accept: */*
>
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0< HTTP/1.1 200 OK
< Content-Length: 399
< Content-Type: application/json; charset=UTF-8
< Vimid: 10a24b40-90ce-43c9-a225-edde2587ff39
< Date: Thu, 28 Sep 2017 04:06:50 GMT
<
{ [data not shown]
100   399  100   399    0     0    893      0 --:--:-- --:--:-- --:--:--   892
* Connection #0 to host 192.168.30.145 left intact
{
    "networks": [
        {
            "NetID": "a851428d-e500-4d11-b266-364035d36e28",
            "adminStateUp": true,
            "external": false,
            "netName": "net1",
            "networkType": "vxlan",
            "physicalNetwork": null,
            "segmentationID": "1057",
            "self": "/v1/networks/a851428d-e500-4d11-b266-364035d36e28",
            "shared": false,
            "status": "ACTIVE",
            "subnets": [
                "2119c378-435f-473c-a59a-d99f79c8dccf"
            ],
            "tenentId": "8c967359b4bd4be2b7989bb0d9524f56"
        }
    ]
}

 

 

同時在發送端網卡抓包查看客戶端和服務端tls加密交互過程:

root@sdn112:~# ssldump -i br-ex
New TCP connection #1: 192.168.30.26(43449) <-> 192.168.30.145(9131) 
1 1  0.0016 (0.0016)  C>S  Handshake
      ClientHello
        Version 3.3
        cipher suites
        Unknown value 0xc030
        Unknown value 0xc02c
        Unknown value 0xc028
        Unknown value 0xc024
        Unknown value 0xc014
        Unknown value 0xc00a
        Unknown value 0xa3
        Unknown value 0x9f
        Unknown value 0x6b
        Unknown value 0x6a
        TLS_DHE_RSA_WITH_AES_256_CBC_SHA
        TLS_DHE_DSS_WITH_AES_256_CBC_SHA
        Unknown value 0x88
        Unknown value 0x87
        Unknown value 0xc032
        Unknown value 0xc02e
        Unknown value 0xc02a
        Unknown value 0xc026
        Unknown value 0xc00f
        Unknown value 0xc005
        Unknown value 0x9d
        Unknown value 0x3d
        TLS_RSA_WITH_AES_256_CBC_SHA
        Unknown value 0x84
        Unknown value 0xc012
        Unknown value 0xc008
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        Unknown value 0xc00d
        Unknown value 0xc003
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        Unknown value 0xc02f
        Unknown value 0xc02b
        Unknown value 0xc027
        Unknown value 0xc023
        Unknown value 0xc013
        Unknown value 0xc009
        Unknown value 0xa2
        Unknown value 0x9e
        TLS_DHE_DSS_WITH_NULL_SHA
        Unknown value 0x40
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA
        TLS_DHE_DSS_WITH_AES_128_CBC_SHA
        Unknown value 0x9a
        Unknown value 0x99
        Unknown value 0x45
        Unknown value 0x44
        Unknown value 0xc031
        Unknown value 0xc02d
        Unknown value 0xc029
        Unknown value 0xc025
        Unknown value 0xc00e
        Unknown value 0xc004
        Unknown value 0x9c
        Unknown value 0x3c
        TLS_RSA_WITH_AES_128_CBC_SHA
        Unknown value 0x96
        Unknown value 0x41
        Unknown value 0xff
        compression methods
                  NULL
1 2  0.0148 (0.0131)  S>C  Handshake
      ServerHello
        Version 3.3
        session_id[32]=
          08 2d cc a8 1a 4a ac 41 d9 74 94 11 20 49 4a da
          23 7e 21 0f 32 98 96 14 c1 a9 88 d3 78 00 6c b4
        cipherSuite         Unknown value 0xc030
        compressionMethod                   NULL
1 3  0.0148 (0.0000)  S>C  Handshake
      Certificate
1 4  0.0148 (0.0000)  S>C  Handshake
      ServerKeyExchange
1 5  0.0148 (0.0000)  S>C  Handshake
      ServerHelloDone
1 6  0.0171 (0.0023)  C>S  Handshake
      ClientKeyExchange
1 7  0.0171 (0.0000)  C>S  ChangeCipherSpec
1 8  0.0171 (0.0000)  C>S  Handshake
1 9  0.0209 (0.0037)  S>C  ChangeCipherSpec
1 10 0.0209 (0.0000)  S>C  Handshake
1 11 0.0213 (0.0003)  C>S  application_data
1 12 0.8137 (0.7924)  S>C  application_data
1 13 0.8142 (0.0004)  C>S  Alert
1    0.8143 (0.0000)  C>S  TCP FIN
1    0.8149 (0.0006)  S>C  TCP FIN

 

 

上面過程服務器就沒有要求客戶端發送客戶端電子證書進行身份認證。從認證過程看,https協商采用TLS1.2/SSL3.3版本,整個握手交互流程都有,加密成功后,客戶端和服務端的http報文就進行加密傳輸,然后通過公共密鑰計算私有密鑰進行解密。這里就可以驗證后台進程可以支持https tls1.2

三、tls 1.2運行交互消息分析

下面我們對比分析訪問https://www.baidu.com的交互過程,抓包分析詳細的消息體內容,抓包信息如下:
完整抓包
如上圖,前面第一個紅框即為客戶端和服務端的通過tcp標志位中的syn/ack的進行三次tcp握手連接,后面紅框為http請求結束后,通過fin/ack關閉tcp連接,中間為采用tls協議建立加密通信的過程,並完成http請求的接受和響應。

具體加密通道的協商過程如下:

3.1 客戶端發出請求(ClientHello)

client hello

客戶端與服務端通過tcp三次握手建立tcp連接后,客戶端首先向服務器發出建立加密通信的請求,發送ClientHello請求,從消息體結構看,tls/ssl是基於tcp連接之上,應用層之下的協議,封裝的消息體內容如下:

 
        
(1) 此時握手協議(handshake protocol)的消息類型為:client hello
(2) 支持的TLS協議版本,比如TLS 1.0版。握手協議的版本為TLS 1.2
(3) 一個客戶端生成的隨機數,稍后用於生成"對話密鑰"。
(4) 支持的加密套件,如Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
(5) 支持的壓縮方法。
(6) 擴展屬性如:服務器名稱(例子中為baidu.com),支持的簽名算法等
 2006年,TLS協議加入了一個Server Name Indication擴展,允許客戶端向服務器提供它所請求的域名。
 
        

 

 

3.2 服務器響應(SeverHello)

服務器收到客戶端請求后,向客戶端發出響應,叫做Sever Hello。

server hello

從消息體中,可以看到服務器的響應包含以下內容:

(1) 確認使用的加密通信協議版本,這里確認使用tls1.2,而不是client hello中的tls1.1。響應握手協議消息 server hello。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信。
(2) 一個服務器生成的隨機數,稍后用於生成"對話密鑰"。
(3) 確認使用的加密套件,這里為rsa+aes128+sha256
(4) 壓縮方法為空。
(5) 一些列擴展信息

 

 

除了上面這些信息,如果服務器需要確認客戶端的身份,就會再包含一項請求,要求客戶端提供”客戶端證書”。比如,金融機構往往只允許認證客戶連入自己的網絡,就會向正式客戶提供USB密鑰,里面就包含了一張客戶端證書。

3.3 服務端發送服務端電子證書(CA),密鑰交換(server key exchange),及server hello done三個握手消息

客戶端接收到server hello握手消息后,及時反饋ack消息。服務端接收客戶端ack消息后,發送服務端電子證書,密鑰交換,及server hello done三個握手消息

ca

從封裝內容看,包含兩層ssl協議體信息,頭一個為服務端證書,后面跟着公共密鑰交換和hello done消息體,具體如下:

1)詳細的電子證書信息和CA認證機構信息
(2)密鑰交換信息,包括DH算法計算出的pubkey公鑰,電子簽名的hash算法值
(3)server hello done消息體

 

 

涉及到兩個問題:

(1)如何保證公鑰不被篡改?
解決方法:將公鑰放在數字證書中。只要證書是可信的,公鑰就是可信的。所以上面報文中就將服務端CA證書和公共密鑰交換消息放在同一個tcp連接進行傳輸。

(2)公鑰加密計算量太大,如何減少耗用的時間?
解決方法:每一次對話(session),客戶端和服務器端都生成一個"對話密鑰"(session key),整個對話密鑰是通過公共密鑰和生成的3個隨機數計算得到,用它來加密信息。由於"對話密鑰"是對稱加密,所以運算速度非常快,而服務器公鑰只用於加密"對話密鑰"本身,這樣就減少了加密運算的消耗時間。

 

 

3.4 客戶端發送密鑰交換信息(client key exchange)、編碼改變協議消息(change cipher spec)

客戶端發送ack消息給服務端,確認收到server hello done消息,然后發送客戶端的密鑰交換信息和修改密鑰的協議消息

client key exchange

主要內容如下:

(1) 發送DH算法計算的pubkey,用於服務端計算生成解密私鑰
(2) 發送編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
(3) 發送加密后的握手消息,一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽
(4) 客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供服務器校驗。(可能在加密消息中,未確認)

 

 

客戶端收到服務器所有響應消息后,首先驗證服務器證書。如果證書不是可信機構頒布、或者證書中的域名與實際域名不一致、或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通信。
如果證書沒有問題,客戶端就會從證書中取出服務器的公鑰,即server key exchange消息中攜帶的pubkey值。然后,根據根據已經收到的三個隨機數計算書加密密鑰,對握手信息進行加密通信,然后向服務器發送上面抓包中三項信息內容。

該步驟中的隨機數,是整個握手階段出現的第三個隨機數,又稱”pre-master key”。有了它以后,客戶端和服務器就同時有了三個隨機數,接着雙方就用事先商定的加密方法,各自生成本次會話所用的同一把”會話密鑰”。

至於為什么一定要用三個隨機數,來生成"會話密鑰",dog250解釋得很好:
"不管是客戶端還是服務器,都需要隨機數,這樣生成的密鑰才不會每次都一樣。由於SSL協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。
對於RSA密鑰交換算法來說,pre-master-key本身就是一個隨機數,再加上hello消息中的隨機,三個隨機數通過一個密鑰導出器最終導出一個對稱密鑰。
pre master的存在在於SSL協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那么pre master secret就有可能被猜出來,那么僅適用pre master secret作為密鑰就不合適了,因此必須引入新的隨機因素。
那么客戶端和服務器加上pre master secret三個隨機數一同生成的密鑰就不容易被猜出了,一個偽隨機可能完全不隨機,可是是三個偽隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。"

 

 

此外,如果前一步,服務器要求客戶端證書,客戶端會在這一步同樣也發送證書及相關信息。更加詳細信息參考HTTPS與TLS

3.5 服務器的最后回應

cepher
服務器收到客戶端的第三個隨機數pre-master key之后,計算生成本次會話所用的”會話密鑰”。然后,向客戶端最后發送下面信息。

1)編碼改變協議,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
(2)服務器握手結束通知,表示服務器的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供客戶端校驗。

 

 

至此,整個握手階段全部結束。接下來,客戶端與服務器進入加密通信,就完全是使用普通的HTTP協議,只不過用”會話密鑰”加密內容。

最后從抓包的報文我們可以看到:Http請求處理響應結束后,客戶端會發送加密的alert消息給服務端,告知如果異常產生變化,就要發出告警。最后就是客戶和服務端發送fin/ack tcp消息關閉tcp連接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM