一、TLS位置及架構
TLS建立在傳輸層TCP/UDP之上,應用層之下。
所以這可以解決一個問題,那就是為什么抓不到HTTP和SMTP包,因為這兩個在TLS之上,消息封上應用層的頭,下到TLS層,TLS層對上層消息整個做了加密,然后套了TLS頭下到傳輸層,套上TCP頭給IP,IP套上IP頭然后路由,找到下一跳之后ARP問MAC地址,然后封上MAC頭,進鏈路層傳輸。所以能看到的是TLS頭、TCP頭,IP頭和MAC頭。
下面這個圖是TLS的架構,TLS內部也分了層,最上層相當于是消息的類型,這幾種類型的消息都要下到Record層,套Record頭,走Record結構來傳輸。
握手協議就是建連接的,改變Cipher spec協議就是協商用到的加密算法什么的東西的,Alert協議是返回一些警報,HTTP就是正常的加密的數據,心跳協議是用來維持連接的。
等下可以通過抓到的包來更清晰的看出來這個架構。
二、TLS握手協議
整體流程如下,從RFC 5246文檔里偷過來的,
Client ServerClientHello -------->ServerHelloCertificate*ServerKeyExchange*CertificateRequest*<-------- ServerHelloDoneCertificate*ClientKeyExchangeCertificateVerify*[ChangeCipherSpec]Finished -------->[ChangeCipherSpec]<-------- FinishedApplication Data <-------> Application Data
1.Phase 1
一步一步看,先看綠色框起來的兩個hello
client hello是第一個消息,注意區分這個握手和TCP握手之間的區別,TCP三次握手是建TCP連接用的,而TLS要走TCP連接,所以在TLS握手之前,TCP已經握完三次手了。
這是訪問一個頁面https協議的過程,雖然不知道為什么所有包都有兩個,但還是可以清晰地看出,TCP三次握手是在TLS ClientHello之前完成的,同時,看TLS下面的這兩個TCP ACK,這也說明了TCP在TLS之下,所以TLS不能加密TCP的頭。
我們來看看這個hello包長什么樣。首先能看出TLS所在的層級,正如剛才所說,他在TCP之上。
其次TLS的內容,這里是handshake Protocol,使用TLS Record protocol封裝,所以TLS的所有內容協議,包括握手協議、改變Cipher spec協議、Alert協議、HTTP、心跳協議都是走Record Layer的,所以實際上TLS分兩層,在TCP緊上面那層是Record 協議,然后在上邊是剩下的協議。
然后看內容吧,對比剛才那張圖,這里包括了TLS的版本,隨機數,session ID,cipher suite(也就是客戶端能接受的加密、認證、密鑰交換算法),還有壓縮方法。剩下的一堆extension列出了更加細節的客戶端所支持的算法,這樣服務器只能在這些列出的里面選擇。
接下來是Server hello,
他會選擇一系列的方法,作為響應回復給Client。這里的一些extension例如session_ticket是用來當session斷開時客戶端快速連接到服務器的憑證,以及下面的對于應用層協議的下協商。
2.Phase 2
這里階段二還是抓個包看看,這wireshark不知道抽什么風,這三個Certificate,Server Key Exchange和Server Hello Done都在一層的一個包里,他給分了兩個。
看這三個東西還都是封到了Record Layer里,這三個分別顧名思義,證書就是服務器把他的X.509證書給客戶端,交換密鑰就是服務器通過hello里跟客戶端商量的協商密鑰算法來交換公鑰,這里是橢圓曲線DH。這之后還有可選的服務器向客戶端要證書。之后就是server hello done表示他這邊結束了,該客戶端了。
別忘了這些包都是走的TCP,到了對方那都要回ACK的。
3.phase 3
前面二階段server發來的證書,client首先會驗一下真假,使用CA的公鑰來驗證證書的簽名。對了之后,首先,如果先前服務器要了客戶端的證書,客戶端會先把他的證書回給服務器。然后他會用server的公鑰來驗server發來的key exchange參數的簽名,之后再生成自己的公鑰交換信息,
這就是下面抓到的包,第一個就是client Key exchange的record。
接下來還有一個certificate verify,這個是只有剛才客戶端發送了有簽名能力的證書才有的一步。
4.phase 4
然后是Change Cipher Spec,這個消息你看長度就1字節,他就是簡單的告訴對方我已經將剛才咱們商量的加密什么的投入使用了,所以他發的接下來的包都是使用剛才協商好的東西加密或認證的了。在這之前,客戶端和服務器交換完密鑰,獲得了一個比如DH公共秘密之后,這個公共秘密叫做pre-master secret,這個結合一些其他的例如隨機數之類的信息,再來生成最終的session key,Change Cipher Spec代表的就是這個最終的session key投入使用。
后面跟的是client finished,這個永遠緊跟在Change Cipher Spec之后,用于驗證整個握手的成功。客戶端會計算之前所有的握手消息的一個mac,加密之后傳給服務器。所以下面抓的包顯示這是加密的信息。
這之后,服務器端收到剛才客戶端發來的那條消息之后,由于之前在hello里說好了要有new session ticket用來之后快速恢復session,所以這第一個record就是new session ticket,然后是服務器端的Change Cipher Spec,之后是服務器的finish,和client的同理,是計算先前的所有握手消息的mac,同樣是加密之后發送。
這之后握手就結束了,這期間任何的錯誤都會引起alert協議報錯,從而終止過程。
三、Alert Protocol
這個就是報各種錯誤,包括下面這些
? bad_record_mac
? handshake_failure
? decryption_failed
? bad_certificate
四、Heartbeat protocol
這個就是周期性的發送信號,比如用來同步。
他有兩個目的,一個是確保雙方還活著,另一個是防止有些防火墻會關閉空閑連接。
五、Record protocol
這個剛才也看了,就是封裝剛才提到的所有的東西的,格式就是下面這樣
content type就會是比如剛才所有握手階段的Record都是handshake(22),實際發的包的type會是Application Data(23),也可能回事Alert(21)等等。
兩個Version就是哪個版本,前面講的例子都是TLSv1.2,長度就是后面的東西有多長。
接下來看看這個Record是怎么生成的吧,比如有加密、認證、分段、壓縮等步驟。
首先拿到具體的數據之后,要分成小于等于2的14次方byte的段,然后如果之前協商了壓縮,那么就會壓縮。
接下來計算MAC然后接上去,對整個東西加密,然后再套上TLS Record的頭,這就是完整的TLS處理完的,可以直接發給下層TCP的東西了。