目錄
1. TLS協議概述
2. 為什么要握手
2.1 Hello
2.2 協商
2.3 同意?
3.總共握了幾次手?
1. TLS協議概述
車內各ECU間基于CAN的安全通訊--SecOC,想必現目前多數通信工程師們都已經搞的差不多了(不要再問FvM了);但是在車云通信時,保證數據的信息安全則常用TLS,搞懂它,加深加深運管端各自的網絡安全機制理解。
TLS(Transport Layer Security)前身叫做SSL(Secure Sockets Layer),位于TCP之上,但仍舊屬于傳輸層,作用很明確,就是為了保證車云通信時數據的CIA。
目前,TLS協議版本已經來到了1.3,具體可以搜版本號RFC 8446,在標準中詳細描述了握手協議,如下圖:
RFC 5246 : TLS v1.2;RFC 4346 : TLS v1.1 ; RFC 2246 TLS v1.0
那么就從最基礎的通信雙方如何建立連接開始,入門TLS。
2. 為什么要握手
握手這個詞很形象,就像相親雙方之前互不認識,但因為家里要求見面,那首先肯定是先握手,握手成功,雙方來電,接下來對話才有戲;握手失敗,閑聊兩句,就各回各家。
握手期間的對話就很講究了,對話如能找到共同話題,那相親雙方就可以圍繞這個話題繼續進行加密通信,這也就是TLS要先握手的本質:協商出一個密鑰(共同話題),讓雙方基于這個密鑰進行加密通信。?
這個協議中定義握手消息名字也很有意思,“Hello”,包括了Client Hello和Server Hello等。
我們以TLS1.2流程為例(因為抓包只抓到TLSV1.2),總結流程如下:
我用Wireshark抓了一個和https網頁溝通的包,過程和上圖很像有么有?
以這個為例來具體分析分析:
2.1 Hello
第一條消息,Client(我)向Server(知乎某專欄)發送Hello請求,得到數據包如下:
該消息體現了當前TLS版本協議、會話ID、隨機數1(很重要記住它)、能夠使用的密碼套件、壓縮算法還有很多擴展內容,特別是有個server_name,就像相親兩人見面第一句一定是,你就是xxx吧?
Client打了招呼,那Server應該要進行回復,不然就沒得聊了,它話很多,打一聲招呼Server Hello,緊接著陸陸續續發送了自己的證書、密鑰交換參數,最終以Hello Done結尾,
Server Hello
格式如下:
Server首先會進行響應,并且從Client能夠使用的密碼套件中選擇一種,在這里,它選擇了0xc02f,滿足第一條消息中提供的密碼套件,這條消息確認了TLS版本1.2,選擇了套件,并且承諾不會壓縮后續對話,注意,這里Server還傳遞了一個隨機數2。
密碼套件名字很長:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,但其實得拆開來看:
ECDHE指的是密鑰交換算法?Elliptic Curve Diffie-Hellman Ephemeral,簽名就使用RSA算法;
AES_128_GCM是指后續加密通信使用AES128-GCM,既定義了密鑰長度,也定義了密碼工作模式;SHA256就很簡單了,做Hash都用它。
Server Certificate
還是以相親為例,兩人見面后的第二句話一定是:我是某某阿姨(中間人)介紹的xxx。
這句話很關鍵,因為相親雙方都是基于中間人的介紹,ta的介紹就像是一個證書,是相親雙方能夠繼續往下聊的一個前提。
但這個中間人只是雙方認可的,如果需要再進一步確認信息,身份證就是最好的證明,這是最權威的機構頒發的證書。
因此,Server Certificate提供證書的目的也很明確,就是證明自己的合法身份,這條消息格式如下:
證書主要包含了如下信息:
證書里包含了一個非常關鍵的內容:Server的公鑰,其他關于證書的問題我們后面單獨再談。
有興趣的可以搜一搜中國電子銀行網的《六問六答》。
Server Key Exchange
前面我們已經知道了,雙方要寫上一個密鑰,使用算法為ECDHE,這個算法要求雙方首先交換公鑰,因此需要這條消息 Key Exchange,格式如下:
這里面包括了握手類型、算法所選曲線采用x25519、用于協商密鑰的公鑰,以及用上述證書中公鑰對應的私鑰進行的簽名,算法為RSA-PSS-SHA256(這些算法填充格式之前已經聊過了)。
Server Hello Done
Hello Done的信息量很少,如下:
?就是Server告訴Client,自我介紹完畢,看你怎么回應。
事實上,通過Wireshark抓包,我們可以看到,Server回應的消息實際是在一個包內,如下圖所示:
2.2 協商
在第一步里,Client收到了Server發來的證書、密鑰交換的參數等等,就需要對一步一步來驗證Server的身份和數據完整性,并向Server發送密鑰協商的參數,同樣一包中可以封裝了不同的消息,如下圖:
Client Key Exchange
首先Client使用CA的公鑰對證書進行驗簽(過程暫不講),通過后取出Server的公鑰備用。
這時候Client就擁有了四個參數:自己的協商公鑰、Server的協商公鑰、隨機數1、隨機數2。
那么神奇的就來了,預協商密鑰 = c_priv * s_pub = c_priv * (s_priv * G);
G是橢圓曲線的基點G,是公開的,唯有私鑰是各自保護,所以Client也要把協商公鑰發給Server,
Server拿到后,計算預協商密鑰 = s_priv * c_pub = s_priv * (c_priv * G)。
這不就妥了嗎?兩邊預協商密鑰都一樣了,這個密鑰一般叫預主密鑰。?
還記得之前兩個隨機數嗎,Client和Server會使用相同算法對這三個參數進行操作,得到最終會話密鑰?= Algo(隨機數1 + 隨機數2 + 預主密鑰)
Change Cipher Spec
這個消息就是告訴Server,咱們密鑰都已經協商好了,那就用它開始進行對話吧,截圖如下:
Encrypted Handshake Message
這個時候就使用了協商好的對稱密鑰對握手消息進行加密傳輸,如下:
之后就是加密后的應用數據了。?
2.3 同意?
當Client發送經過對稱加密的消息后,Server當然也需要進行確認,因此會回復三個消息:
New Session Ticket
該消息主要是為了快速恢復會話,防止重復握手
Change Cipher Spec?
表示Server接收到了使用協商好的共享密鑰,并且確認后續都使用該密鑰進行加密通話。
Encrypted Handshake Message
3.總共握了幾次手?
最后總結一下, TLS建立連接時總共進行了幾次握手?
第一次:Client向Server發送 Client Hello,包括協議的版本信息、密碼套件、隨機數(Client Random)等;
第二次:Server向Client發送 Server Hello,包括所選密碼套件、協議版本、數字證書、隨機數(Server Random);
第三次:Client向Server發送協商密鑰的參數、更新加密協議、發送密文等;
第四次:Server向Client發送新建會話Tickets、發送密文以驗證對稱加解密通道;
這就是TLS的四次握手成功。
?