MQTT研究之EMQ:【wireshark抓包分析】

基於上篇博文【SSL雙向驗證】的環境基礎,進行消息的具體梳理.html

環境基礎信息:算法

1. 單臺Linux CentOS7.2系統,安裝一個EMQTTD的實例broker。
2. emq的版本2.3.113. 客戶端分爲mosquitto_pub,以及MQTT.fx 1.7.1的subscriber。
4. 證書是經過openssl(version:1.0.2k-fips)生成的,rootCA是自簽名的,subscriber和publisher的證書是經過rootCA簽署的。
5. 抓包工具wireshark(version: 2.6.6,下載地址https://www.wireshark.org/download/win64/),分析SSL/TLS通訊的消息流.

 

第一步:經過wireshark抓取SSL雙向驗證的消息緩存

下面是我測試過程當中,獲得的消息流程,個人測試環境,在TLS的兩層消息結構(record layer,handshake layer)中的握手協議環節,獲得的cipher suite的值是:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384服務器

先簡單介紹下,這個cipher suite的含義,這個應該是SSL/TLS協議中比較難以理解的一個概念。這個說簡單點,就是祕鑰協商(Key agreement)的頂層設計,後續的消息流程都是密切的基於這個cipher suite的值而有較大的不一樣,準確的說,祕鑰交換(Key exchange)和上訴紅色部分關係最爲密切.app

一、祕鑰協商和祕鑰交換這兩個概念,看到不少地方的討論和描述中,彷佛沒有區分的很明確,依據個人理解,祕鑰協商和祕鑰交換,確實有很大的關聯性,不可能徹底割裂或者分離關係,只是兩個概念描述的側重點不一樣,祕鑰協商更多表述怎麼作這個邏輯,而祕鑰交換,更多側重怎麼作的實際動做或者流程ide

二、cipher suite的簡單介紹工具

就拿我這個測試的cipher suite值說明吧。測試

TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384ui

        鍵值交換籤名協議       數據加密算法       信息認證碼算法this

更詳細的介紹,能夠對照下面這個圖:

祕鑰協商/交換,是爲了在握手的過程當中,基於給定的cipher suite完成shared secret的生成過程,這個祕鑰就是用來爲後續數據傳輸的時候對稱加密用的密碼信息驗證碼協議,是爲了保證數據傳輸的時候的數據一致性或者完整性的。

 

在咱們這個測試中,基於上述cipher suite獲得的消息流以下:

C->S: Client Hello
S->C: Server Hello
S->C: Certificate,Server Key Exchange, Certificate Request, Server Hello Done
C->S: Certificate, Client Key Exchange
C->S: Certificate Verify,Change Cipher Spec,Encrypted Handshake Message
S->C: Change Cipher Spec,Encrypted Handshake Message
C->S: Application Data
S->C: Application Data

a. C->S: Client Hello

 

b. S->C: Server Hello

 

c. S->C: Certificate,Server Key Exchange, Certificate Request, Server Hello Done (這裏的Certificate Request,就是服務端要求客戶端上報證書

 

d. C->S: Certificate, Client Key Exchange (這個環節很重要,體現了雙向SSL驗證的特徵了,服務端要求的身份驗證,即但願校驗客戶端的證書的過程)

 

e. C->S: Certificate Verify,Change Cipher Spec,Encrypted Handshake Message

這個消息,其實理解起來彷佛有點很差理解。爲什麼客戶端要上報Certificate Verify呢

1). certificate Verify消息必須在client key exchange後面由客戶端發出去給服務器端。
2). 這個消息,是客戶端構建的,內容是客戶端收發的全部的handshake消息(不含當前這個Verify的消息)拼接後的內容進行hash,而後用證書對應的私鑰進行簽名後所得的內容S1。
3). 這個消息,服務端會進行驗證。驗證的邏輯,經過對服務端緩存的客戶端消息,以及服務端發送的全部handshake消息,一樣進行拼接而後計算hash值h2,用客戶端的證書中的公鑰解析Verify中的簽名S1獲得對應的hash值h1,對比h1和和
,若相同,則驗證經過,不然失敗。

能夠參考這個連接中的內容,其實,他的解釋或者介紹,也是基於RFC文檔中的內容進行的,只是比較白話了,相對好懂些。

 

f. S->C: Change Cipher Spec,Encrypted Handshake Message

 

g.C->S: Application Data

 

第二步:單向SSL驗證(客戶端驗證服務端的合法性)

1. 配合broker

## Path to the file containing the user's private PEM-encoded key.
##
## See: http://erlang.org/doc/man/ssl.html
##
## Value: File
#listener.ssl.external.keyfile = /etc/emqttd/certs/key.pem
listener.ssl.external.keyfile = /opt/certs/server.key

## Path to a file containing the user certificate.
##
## See: http://erlang.org/doc/man/ssl.html
##
## Value: File
#listener.ssl.external.certfile = /etc/emqttd/certs/cert.pem
listener.ssl.external.certfile = /opt/certs/server.crt

## Path to the file containing PEM-encoded CA certificates. The CA certificates
## are used during server authentication and when building the client certificate chain.
##
## Value: File
## listener.ssl.external.cacertfile = /etc/emqttd/certs/cacert.pem
listener.ssl.external.cacertfile = /opt/certs/rootCA.crt

## The Ephemeral Diffie-Helman key exchange is a very effective way of
## ensuring Forward Secrecy by exchanging a set of keys that never hit
## the wire. Since the DH key is effectively signed by the private key,
## it needs to be at least as strong as the private key. In addition,
## the default DH groups that most of the OpenSSL installations have
## are only a handful (since they are distributed with the OpenSSL
## package that has been built for the operating system it’s running on)
## and hence predictable (not to mention, 1024 bits only).
## In order to escape this situation, first we need to generate a fresh,
## strong DH group, store it in a file and then use the option above,
## to force our SSL application to use the new DH group. Fortunately,
## OpenSSL provides us with a tool to do that. Simply run:
## openssl dhparam -out dh-params.pem 2048
##
## Value: File
## listener.ssl.external.dhfile = /etc/emqttd/certs/dh-params.pem

## A server only does x509-path validation in mode verify_peer,
## as it then sends a certificate request to the client (this
## message is not sent if the verify option is verify_none).
## You can then also want to specify option fail_if_no_peer_cert.
## More information at: http://erlang.org/doc/man/ssl.html
##
## Value: verify_peer | verify_none
listener.ssl.external.verify = verify_none #主要是在雙向驗證的基礎上將此配置改成verify_none

## Used together with {verify, verify_peer} by an SSL server. If set to true,
## the server fails if the client does not have a certificate to send, that is,
## sends an empty certificate.
##
## Value: true | false
## listener.ssl.external.fail_if_no_peer_cert = true

 

2. 經過wireshark抓取SSL消息流

具體的經過wireshark抓取SSL消息流

C->S: Client Hello
S->C: Server Hello
S->C: Certificate, Server Key Exchange, Server Hello Done
C->S: Client Key Exchange
C->S: Change Cipher Spec, Encrypted Handshake Message
S->C: Change Cipher Spec, Encrypted Handshake Message
C->S: Application Data
S->C: Application Data
......
S->C: Encrypted Alert
C->S: Encrypted Alert

 

最後,補充一下,關於DH祕鑰交換的流程圖,ECDH交換和DH交換流程邏輯相同,只是算法中交換的參數計算邏輯不一樣而已,從DH升級到ECDH是能夠平滑作到的。

ECDH祕鑰交換說明

假設密鑰交換雙方爲Alice、Bob,其有共享曲線參數(橢圓曲線E、階N、基點G),對於於上圖中的common paint黃色信息,是你們共有的,只是每次協商時,值不一樣,可是雙方都是知道的

1.Alice生成隨機整數a (對應上圖中的orange,計算A=a*G(這個A,對應上圖中orange-tan)。Bob生成隨機整數b(對應上圖中的blue-green,計算B=b*G(這個B,對應上圖中的light-blue)。

2.Alice將A傳遞給Bob。A的傳遞能夠公開,即攻擊者能夠獲取A。因爲橢圓曲線的離散對數問題是難題,因此攻擊者不能夠經過A、G計算出a。Bob將B傳遞給Alice。同理,B的傳遞能夠公開。

3.Bob收到Alice傳遞的A,計算Q=b*A 這裏的Q,對應上圖中yellow-brown

4.Alice收到Bob傳遞的B,計算Q‘=a*B這裏的Q‘,對應上圖中yellow-brown

Alice、Bob雙方即得Q=b*A=b*(a*G)=(b*a)*G=(a*b)*G=a*(b*G)=a*B=Q' (交換律和結合律),即雙方獲得一致的密鑰Q。

 

到此,整個祕鑰交換爲核心的SSL消息流,大致就算是弄清楚了。

相關文章
相關標籤/搜索