04.安全-TLS1.2連接過程

TLS 握手的前幾個消息都是明文的,能夠在 Wireshark 裏直接看。

但只要出現了“Change Cipher Spec”,後面的數據就都是密文了,看到的也就會是亂碼,不知道究竟是什麼東西。

爲了更好地分析 TLS 握手過程,可以再對系統和 Wireshark 做一下設置,讓瀏覽器導出握手過程中的祕密信息,這樣 Wireshark 就可以把密文解密,還原出明文。

首先,你需要在 Windows 的設置裏新增一個系統變量SSLKEYLOGFILE,設置瀏覽器日誌文件的路徑,比如

D:\http_study\log\sslkey.log

然後在 Wireshark 裏設置“Protocols-TLS”
(較早版本的 Wireshark 裏是“SSL”),在“(Pre)-Master-Secret log filename”裏填上剛纔的日誌文件

ECDHE握手過程


在 TCP 建立連接之後,瀏覽器會首先發一個“Client Hello”消息,也就是跟服務器“打招呼”。
裏面有客戶端的版本號、支持的密碼套件,還有一個隨機數(Client Random),用於後續生成會話密鑰

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 512
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 508
            Version: TLS 1.2 (0x0303)
            Random: deb646e741a099b49bfef08f38871a4ac8d86b1f265ea6dc…
            Session ID Length: 32
            Session ID: 559393da63fd63f325d1f52088aa649401260c65f1e499fc…
            Cipher Suites Length: 34
            Cipher Suites (17 suites)
            Compression Methods Length: 1
            Compression Methods (1 method)
            Extensions Length: 401
            Extension: Reserved (GREASE) (len=0)
            Extension: server_name (len=19)
            Extension: extended_master_secret (len=0)
            Extension: renegotiation_info (len=1)
            Extension: supported_groups (len=10)
            Extension: ec_point_formats (len=2)
            Extension: session_ticket (len=0)
            Extension: application_layer_protocol_negotiation (len=14)
            Extension: status_request (len=5)
            Extension: signature_algorithms (len=20)
            Extension: signed_certificate_timestamp (len=0)
            Extension: key_share (len=43)
            Extension: psk_key_exchange_modes (len=2)
            Extension: supported_versions (len=11)
            Extension: compress_certificate (len=3)
            Extension: Reserved (GREASE) (len=1)
            Extension: padding (len=202)

作爲“禮尚往來”,服務器收到“Client Hello”後,會返回一個“Server Hello”消息。

把版本號對一下,也給出一個隨機數(Server Random),
然後從客戶端的列表裏選一個作爲本次通信使用的密碼套件,在這裏它選擇了“TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384”

Transport Layer Security
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 112
        Handshake Protocol: Server Hello
            Handshake Type: Server Hello (2)
            Length: 108
            Version: TLS 1.2 (0x0303)
            Random: 306ba0a553a042f119e52473b67c6e293f3ee61012fff8ff…
            Session ID Length: 32
            Session ID: 27e4112dd0e1299b7fd853c7787c16308bf03435a620a8fd…
            Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
            Compression Method: null (0)
            Extensions Length: 36
            Extension: renegotiation_info (len=1)
            Extension: server_name (len=0)
            Extension: ec_point_formats (len=4)
            Extension: extended_master_secret (len=0)
            Extension: application_layer_protocol_negotiation (len=11)
    TLSv1.2 Record Layer: Handshake Protocol: Certificate
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 770
        Handshake Protocol: Certificate
            Handshake Type: Certificate (11)
            Length: 766
            Certificates Length: 763
            Certificates (763 bytes)
                Certificate Length: 760
                Certificate: 308202f4308201dca003020102020900fa9c5b27a0c1368d… (id-at-commonName=www.chrono.com)
                    signedCertificate
                    algorithmIdentifier (sha256WithRSAEncryption)
                    Padding: 0
                    encrypted: 6dd90318e47d1b41728f04802a85eedca00a615feed7a67f…
    TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 300
        Handshake Protocol: Server Key Exchange
            Handshake Type: Server Key Exchange (12)
            Length: 296
            EC Diffie-Hellman Server Params
                Curve Type: named_curve (0x03)
                Named Curve: x25519 (0x001d)
                Pubkey Length: 32
                Pubkey: 780f25b44d2ebb5df7ead5e9b6b32c2d40bb7094f16ac7c6…
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Length: 256
                Signature: 6778592c6742cbd45ff120ce72d1a442a8c5cdbb65e792d5…
    TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 4
        Handshake Protocol: Server Hello Done
            Handshake Type: Server Hello Done (14)
            Length: 0


然後,服務器爲了證明自己的身份,就把證書也發給了客戶端(Server Certificate)。

接下來是一個關鍵的操作,因爲服務器選擇了 ECDHE 算法,所以它會在證書後發送“Server Key Exchange”消息,裏面是橢圓曲線的公鑰(Server Params),用來實現密鑰交換算法,再加上自己的私鑰簽名認證

TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
        Content Type: Handshake (22)
        Version: TLS 1.2 (0x0303)
        Length: 300
        Handshake Protocol: Server Key Exchange
            Handshake Type: Server Key Exchange (12)
            Length: 296
            EC Diffie-Hellman Server Params
                Curve Type: named_curve (0x03)
                Named Curve: x25519 (0x001d)
                Pubkey Length: 32
                Pubkey: 780f25b44d2ebb5df7ead5e9b6b32c2d40bb7094f16ac7c6…
                Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
                    Signature Hash Algorithm Hash: SHA512 (6)
                    Signature Hash Algorithm Signature: RSA (1)
                Signature Length: 256
                Signature: 6778592c6742cbd45ff120ce72d1a442a8c5cdbb65e792d5…
  • 1.指明自己使用的橢圓曲線(一般根據客戶端的拓展中supported_groups中的選擇橢圓曲線算法)

  • 2 服務器本地計算一個大數(BIGNUM),乘上曲線的base point,得到一個新的point,這個point就是公鑰,用04+x+y的格式組織起來。04表示unconpressed point,和客戶端的ec_point_formats有關。

  • 3 簽名 。和RSA握手不同,RSA情況下, 只要能值正常協商密鑰,那麼必然服務器端有證書對應的私鑰,也間接表明了服務器擁有該證書。
    DHE/ECDHE不同,證書對應的私鑰並不參與密鑰協商,如果要證明服務器擁有證書,則必然有簽名的操作(就像雙向認證的情況下,客戶端需要發送certificate verify)。
    被簽名數據從curve type起,至point的y爲止。
    對於TLS1.2,簽名算法使用client hello拓展中提供的摘要算法;TLS1.0和TLS1.1,如果本地證書是ECC證書,即若要使用ECDSA簽名,這種摘要算法爲SHA1,其他的情況摘要算法爲md5+sha1。

計算摘要之後就調用RSA或者ECDSA進行簽名。注意的是,TLS1.2時報文要帶上2字節的“Signature Hash Algorithm”,如上圖高亮部分,這是TLS1.2協議相較於之前協議不同之處之一,但是這2部分不參與簽名計算

這相當於說:“剛纔我選的密碼套件有點複雜,所以再給你個算法的參數,和剛纔的隨機數一樣有用,別丟了。爲了防止別人冒充,我又蓋了個章。

”之後是“Server Hello Done”消息,服務器說:“我的信息就是這些,打招呼完畢。”這樣第一個消息往返就結束了(兩個 TCP 包),結果是客戶端和服務器通過明文共享了三個信息:Client Random、Server Random 和 Server Params。

客戶端這時也拿到了服務器的證書,那這個證書是不是真實有效的呢?
開始走證書鏈逐級驗證,確認證書的真實性,再用證書公鑰驗證簽名,就確認了服務器的身份:“剛纔跟我打招呼的不是騙子,可以接着往下走。”然後,客戶端按照密碼套件的要求,也生成一個橢圓曲線的公鑰(Client Params),用“Client Key Exchange”消息發給服務器。

Handshake Protocol: Client Key Exchange
    EC Diffie-Hellman Client Params
        Pubkey: 8c674d0e08dc27b5eaa…

現在客戶端和服務器手裏都拿到了密鑰交換算法的兩個參數(Client Params、Server Params),就用 ECDHE 算法一陣算,算出了一個新的東西,叫“Pre-Master”,其實也是一個隨機數。

至於具體的計算原理和過程,因爲太複雜就不細說了,但算法可以保證即使黑客截獲了之前的參數,也是絕對算不出這個隨機數的。

現在客戶端和服務器手裏有了三個隨機數:Client Random、Server Random 和 Pre-Master。
用這三個作爲原始材料,就可以生成用於加密會話的主密鑰,叫“Master Secret”。而黑客因爲拿不到“Pre-Master”,所以也就得不到主密鑰。爲什麼非得這麼麻煩,非要三個隨機數呢?

這就必須說 TLS 的設計者考慮得非常周到了,他們不信任客戶端或服務器僞隨機數的可靠性,爲了保證真正的“完全隨機”“不可預測”,把三個不可靠的隨機數混合起來,那麼“隨機”的程度就非常高了,足夠讓黑客難以猜測。

master_secret = PRF(pre_master_secret, "master secret",
                    ClientHello.random + ServerHello.random)

這裏的“PRF”就是僞隨機數函數,它基於密碼套件裏的最後一個參數,比如這次的 SHA384,通過摘要算法來再一次強化“Master Secret”的隨機性。

主密鑰有 48 字節,但它也不是最終用於通信的會話密鑰,還會再用 PRF 擴展出更多的密鑰,比如客戶端發送用的會話密鑰(client_write_key)、服務器發送用的會話密鑰(server_write_key)等等,避免只用一個密鑰帶來的安全隱患。

有了主密鑰和派生的會話密鑰,握手就快結束了。客戶端發一個“Change Cipher Spec”,然後再發一個“Finished”消息,把之前所有發送的數據做個摘要,再加密一下,讓服務器做個驗證。

意思就是告訴服務器:“後面都改用對稱算法加密通信了啊,用的就是打招呼時說的 AES,加密對不對還得你測一下。

”服務器也是同樣的操作,發“Change Cipher Spec”和“Finished”消息,雙方都驗證加密解密 OK,握手正式結束,後面就收發被加密的 HTTP 請求和響應了

  • HTTPS 協議會先與服務器執行 TCP 握手,然後執行 TLS 握手,才能建立安全連接
  • 握手的目標是安全地交換對稱密鑰,需要三個隨機數,第三個隨機數“Pre-Master”必須加密傳輸,絕對不能讓黑客破解;
  • “Hello”消息交換隨機數,“Key Exchange”消息交換“Pre-Master”;
  • “Change Cipher Spec”之前傳輸的都是明文,之後都是對稱密鑰加密的密文

TLS協議組成

記錄協議

Record Protocol ,規定了TLS收發數據的基本單位。它有點類似TCP裏的segment,所有的其它子協議都需要通過記錄協議發出
但是多個記錄數據可以在1個TCP包裏一次性發出,也並不需要像TCP那樣返回ACK

警報協議

Alert protocol 職責是向對方發出警報信息,類似http協議裏的狀態碼。
比如protocol_version 就死不支持舊版本 bad_certificate就是證書有問題
收到警報後,另一方可以選擇終止連接,也可以選擇繼續

握手協議

(Handshake Protocol)是 TLS 裏最複雜的子協議,要比 TCP 的 SYN/ACK 複雜的多,瀏覽器和服務器會在握手過程中協商

  • TLS 版本號、
  • 隨機數、
  • 密碼套件等信息,

然後交換證書和密鑰參數,最終雙方協商得到會話密鑰,用於後續的混合加密系統

變更密碼規範協議

(Change Cipher Spec Protocol),它非常簡單,就是一個“通知”,告訴對方,後續的數據都將使用加密保護。那麼反過來,在它之前,數據都是明文的

第一階段:C/S兩端共享Client Random、Server Random 和 Server Params信息
客戶端--->服務器:
客戶端的版本號、支持的密碼套件,還有一個隨機數(Client Random)

服務端--->客戶端:
客戶端的版本號、選擇的客戶端列表的密碼套件如:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384、隨機數隨機數(Server Random)

服務端--->客戶端:
服務端證書(Server Certificate)


服務端--->客戶端:
發送Server Key Exchange類型的請求,攜帶橢圓曲線的公鑰(Server Params)用以實現密鑰交換算法,另附私鑰簽名


服務端--->客戶端:
發送完畢


第二階段:證書驗證

前驗條件:客戶端證書鏈逐級驗證、證書公鑰驗證簽名,服務端身份驗證成功(證書合法)

客戶端--->服務端
發送Client Key Exchange類型的請求,攜帶橢圓曲線的公鑰(Client Params)用以實現祕鑰交換算法


第三階段:主密鑰生成

客戶端、服務端分別使用Client Params、Server Params通過ECDHE算法計算出隨機值pre-master,然後用
Client Random、Server Random 和 Pre-Master三個值作爲原材料,用PRF僞隨機數函數(利用密碼套件的摘要算法再次強化結果
值maser secert的隨機性)計算出主密鑰Master Secret,

主密鑰並不是會話祕鑰,還會再用PRF擴展出更多的密鑰,比如客戶端發送用的會話密鑰(client_write_key)、服務器發送用的會話密鑰(server_write_key)


客戶端--->服務端:
客戶端發一個“Change Cipher Spec”,然後再發一個“Finished”消息,把之前所有發送的數據做個摘要,再加密一下,讓服務器做個驗證.

服務端--->客戶端:
服務器也是同樣的操作,發“Change Cipher Spec”和“Finished”消息,雙方都驗證加密解密 OK,握手正式結束.

1.client hello 【client->server】

  • client發送 隨機數randomC,tls版本,支持的密碼套件,擴展信息到服務端

2.server hello 【server-client】

  • server 發送 隨機數randomS,tls版本確認,選擇的密碼套件,擴展信息到client

3.certificate 【server->client】

4.server key exchange 【server->client】

  • EC Diffie-Hellman Server Params
    • Curve Type(曲線類型)
    • Pubkey
    • Signature Algorithm和Signature

5.server hello done 【server ->client】

https://blog.csdn.net/mrpre/article/details/78025940

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章