1、根據公開資料顯示,xxxx的聊天通信協議mmtls是基於tls 1.3精簡了一些握手的方法后用openssl實現的;官方的介紹在這:https://mp.weixin.qq.com/s/tvngTp6NoTZ15Yc206v8fQ ;為了便於理解、抓住主脈絡,我這里整理了整個協議的主干思路,如下:

完整的TLS流如下:
下面挨個分析這些包的作用和重要字段的意義!
- 老規矩,主動向server打招呼的時候先做個自我介紹:這個是handshake握手包,版本是1.0(我暫時也不知道為什么是這個),這個包的長度是512字節;(注意: tcp協議的缺點之一:必須明文指定包長度!接收方按照指定的長度讀取數據。windows下有個 CVE-2020-16898 "Bad Neighbor " https://www.cnblogs.com/theseventhson/p/14004712.html 就是因為內核驅動沒處理好接受的數據包長度導致藍屏;這個地方還有可能利用整數溢出漏洞,進而導致緩沖區溢出)

接下來是核心的handshake protocol解析,如下:字段有很多,我們挨個看

前面3個handshake type、length、version都是常規的介紹,看英文不解釋都能懂!從第4個開始:
- random:client隨機生成一個32byte的數發給server。通常,在通信中以訪給另一方發隨機數的作用有:1)防止重放攻擊 2)后續用於完整性校驗,這里也不例外 3)生成encrypt-key,正式開始加密應用層的數據;
- session ID:雙方通信的一般套路都是“非對稱算法協商密鑰,對稱算法加密數據”。服務器生成session id,存放本次session協商好的對稱密鑰。下次通信時,客戶端帶上session id,server就知道用哪個對稱密鑰繼續加密數據了。不過session id有些缺陷(id一般都存在單個服務器,但客戶端的數據一般都是反向代理、負載均衡等轉發到內部某個server的,這些反向代理、負載均衡是不知道session id屬於哪個server),已經被session ticket替代;
- cipher suites:client列舉自己支持的加密套件,可以看出前面一般是非對稱加密算法,協商對稱算法密鑰的。后面都是加密應用數據的對稱算法;后續server會根據自己的實際情況選擇合適的加密套件;這里稍微解釋一下這些加密套件的基礎算法,比如:0xc02b,ECDHE,是雙方用來協商對稱密鑰的橢圓曲線算法;ECDSA是客戶端驗證服務端的簽名算法;AES_128_GCM_SHA256是128bit的對稱加密算法,同時帶了數據校驗功能,可有效識別傳輸的數據是否被篡改!
- extension:有好多分項,都有不同的含義,先看第一個:說明server name。這里訪問的是gstatic,貌似是google的廣告聯盟站點。我並沒有訪問這個,估計是訪問google時自帶的;
- supported groups:由於安全性和效率問題,tls1.3已經不再使用RSA,而是橢圓曲線。不同的橢圓曲線對應不同的曲線形狀,會產生不同的公鑰;同樣,不同的基點G也會導致產生不同的公鑰,所以這里有4種不同的橢圓曲線參數供client選擇;
- session ticket:作用和session id類似,上面已經解釋過了。這里由於還是client hello階段,所以這個字段暫時沒有值;保留字段,帶上空值,也可以向服務器標明client支持session ticket功能;
- application layer protocol negotiation:協商tls上層的應用層協議,這里采用的是http協議
- key share:這個是重點!tls1.3支持1-RTT,比tls1.2效率提升一倍,原因就在這里了:在client hello里面,client列舉出了自己支持的加密套件,並把所有的非對稱加密算法的公鑰都一並帶上(雖說這里只有1種,我懷疑是瀏覽器的問題)。server收到后可以直接根據接受的ECDHE和client的公鑰生成自己的公鑰和對稱密鑰;
- PSK exchange models:psk_dhe_ke=1,這里雙方約定用非對稱加密方法ECDHE協商一個對稱密鑰,或則直接從之前協商出來的密鑰參數中得出一個密鑰(psk_ke);
- supported version:支持的tls版本,這里大概是為了兼容老版本,從tls1.0到1.3都支持
- pre-shared key:訪問googke另一個分站點的時候,抓到了PSK的字段,如下:(1)psk本質也是一串ID,這里有226byte,生成方式見本文上方的那張圖,最早是server和client通過tls成功握手后把key和其他一些信息通過HMAC轉換后發給client;client后續訪問可以直接帶上這個PSK,就不用再做密鑰協商,節約時間;(2)這里還有個obfuscated ticket age: 1874391131,轉成年月日的格式就是2029-05-25 16:12:11,這是PSK的生存時間,過期就用不了了。
注意幾個容易混淆的概念:
- key_share:橢圓曲線中雙方互換公鑰來生成對稱加密的私鑰; pre_shared_key:是預共享秘鑰認證機制PSK生成的對稱秘鑰,PSK也是一種身份認證機制;
- psk其實即使Session ticket外加一些檢驗的東西,相當於ticket的強化版!
上面介紹了那么多extension,有4個extension是必須的:psk_key_exchange_modes、pre_shared_key、key_share、supported_versions;
(2)server hello:先來看前面遺留的第一個問題:為啥client hello之后server先發一個ack給client,再發server hello了?而不是直接發個server hello?
server hello要根據client的加密套件、公鑰繼續算出自己公鑰和私鑰(32byte=258bit),這種big num的計算是相當耗時的(這里花了約440ms)。如果server在收到client hello后不馬上回復ACK,而是等計算出自己公鑰和私鑰再回復client,搞不好client會認為server已經超時掛掉,所以server先發個ACK,讓client知道他的hello包已經被收到!
和分析client hello包一樣,接下來挨個分析重要字段的含義:
- 還是標明這個包的作用是handshake,長度122字節,版本是1.2(也不知道為啥不標注1.3)......
- Random: 32byte的隨機數,作用和之前client發給server的隨機數一樣,1)防止重放 2)后續用於消息完整性校驗,防止被篡改 3)生成encrypt-key,正式開始加密應用層的數據;
- session id:32byte,作用在client那里已經解釋了
- Cipher Suite:client在client hello包里面列舉了其能支持的加密套件,這里server在里面選擇了這個加密套件;后續雙方就用AES_GCM來做對稱加密;
- Extensions:最重要的莫過於key_share了。對稱加密算法是AES_GCM,那么密鑰又是啥了? 就是通過橢圓曲線計算出來的;Client在hello包里已經給server發送了他的公鑰,server也要把自己的公鑰發給client,雙方才能計算出對稱加密的密鑰,所以server這里選擇了x25519(這個其實是client選擇的,server只能遵從)。
- Change Cipher Spec:告訴client,后續咋們通信時改變現在的加密方式,即改成對稱密鑰加密通信數據;
剩下的問題又來了:wireshark就解析到了0xba這個位置,從0xbb到0x58e=1422的位置,還有1234byte並未解析,這些又都是什么數據了?縱觀整個協議的握手過程,截至目前看到的都是handshake密鑰交換階段,record傳輸加密數據的階段都在哪了?
4、總結:
(1) 剛開始學的時候,對session id、ticket、psk理解不夠透徹,很多概念的解釋看的雲里霧里,這里系統性對比和總結這3個概念的區別,希望對讀者有所幫助;
(2)整個過程涉及到client和server雙方互換公鑰和生成對稱密鑰。期間只有client驗證server,並沒有server驗證client,這里有個缺陷:如果黑客冒充client(這個不難,比如隨機更換源IP,導致server認為是來自不同client的包),隨機生成各種公鑰(甚至都不用隨機生成,而是直接寫死),server接收到client的公鑰后要需要耗費算計去計算對稱密鑰。如果黑客偽造的client達到一定數量,理論上可以導致server的CPU耗盡,無法再接受正常client的鏈接請求,這也是常見的DOS攻擊之一!
參考:
1、https://blog.csdn.net/SkyChaserYu/article/details/105840504 tls1.3抓包分析
2、https://time.geekbang.org/comment/nice/111287 session id、session ticket、psk三者區別和聯系
3、https://halfrost.com/https_tls1-3_handshake/ 直觀感受tls握手流程
4、https://jasonlees.netlify.app/article/tcpip-4-ssl-tls-3/ TCP/IP系列(4)-SSL/TSL詳解(3)
5、https://cshihong.github.io/2019/05/09/SSL%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3/ SSL協議詳解