通過(guò)局域網(wǎng)中間人攻擊學(xué)網(wǎng)絡(luò) 續(xù) HTTPS篇2
通過(guò)局域網(wǎng)中間人攻擊學(xué)網(wǎng)絡(luò) 續(xù)
續(xù) HTTPS篇2
抓包環(huán)境
本章開(kāi)始分析握手包,分析過(guò)程中會(huì)涉及抓包,為了盡可能方便,后續(xù)都采用對(duì)百度的抓包,工具;wireshark,使用過(guò)濾條件(不過(guò)濾的話包太多不好找):?tls.handshake.extensions_server_name == ss2.baidu.com
Record數(shù)據(jù)結(jié)構(gòu)
HTTPS中數(shù)據(jù)都是通過(guò)Record層進(jìn)行包裝的,Record的數(shù)據(jù)結(jié)構(gòu)如下:
public class Record{
/**
* 一個(gè)byte的contentType
*/
private byte contentType;
/**
* 兩個(gè)byte的版本號(hào),高8位是主版本號(hào),低8位是副版本號(hào)
*/
private short version;
/**
* 兩個(gè)byte的長(zhǎng)度字段,表示后邊數(shù)據(jù)的長(zhǎng)度
*/
private short length;
private T content;
}
其中contentType是一個(gè)枚舉值,枚舉如下:
0x14: CHANGE_CIPHER_SPEC(更換到加密通道通知)
0x15: ALTER(警告信息)
0x16: HANDSHAKE(握手消息)
0x17: APPLICATION_DATA(應(yīng)用數(shù)據(jù))
其中CHANGE_CIPHER_SPEC、ALTER、HANDSHAKE都有可能在握手階段發(fā)送;
version也是一個(gè)枚舉值,枚舉如下:
0x0301: TLS1.0
0x0302: TLS1.1
0x0303: TLS1.2(目前已發(fā)布的最新版就是這個(gè)版本,TLS1.3還處在草案中)
ClientHello
ClientHello的數(shù)據(jù)結(jié)構(gòu)如下:
public class ClientHello{
/**
* 1byte的握手類(lèi)型
*/
private byte handshakeType;
/**
* 3byte的長(zhǎng)度字段,表示后續(xù)數(shù)據(jù)長(zhǎng)度;注意:雖然這里定義的是int,但是實(shí)際網(wǎng)絡(luò)傳輸中只使用了3byte而不是4byte
*/
private int len;
/**
* 2byte的版本號(hào)
*/
private short version;
/**
* 固定32byte的客戶端隨機(jī)數(shù),密鑰交換的時(shí)候會(huì)用
*/
private byte[] random;
/**
* 1byte的session長(zhǎng)度,恢復(fù)會(huì)話的時(shí)候會(huì)用,首次連接固定是0
*/
private byte sessionLen;
/**
* sessionLen 長(zhǎng)度的session byte數(shù)組
*/
private byte[] session;
/**
* 密碼套件數(shù)據(jù)長(zhǎng)度,注意:不是密碼套件的數(shù)量,而是所有密碼套件序列化后的字節(jié)數(shù)組長(zhǎng)度
*/
private short cipherSuitesLen;
/**
* 密碼套件,一個(gè)密碼套件為2byte(即一個(gè)short)
*/
private List<Short> cipherSuites;
/**
* 壓縮方法長(zhǎng)度,因?yàn)橐恍┌踩珕?wèn)題目前壓縮已經(jīng)禁用了;
*/
private byte compressionMethodLen;
/**
* 壓縮方法byte數(shù)組,因?yàn)閴嚎s方法禁用了,所以目前長(zhǎng)度固定0;
*/
private byte[] compressionMethod;
/**
* 2byte的擴(kuò)展長(zhǎng)度
*/
private shrot extensionsLen;
/**
* 擴(kuò)展
*/
private List<Extension> extensions;
}
HTTPS握手的第一步就是一個(gè)ClientHello消息,我們先通過(guò)wireshark抓一個(gè)包來(lái)看看,wireshark抓包如下(開(kāi)啟wireshark后通過(guò)瀏覽器訪問(wèn)百度):

可以看到,這個(gè)是完全符合我們上邊定義的,clientHello中特別關(guān)注的有幾個(gè),分別是random、cipherSuite和extension;
random
這個(gè)是密鑰交換過(guò)程中需要使用的,需要使用隨機(jī)數(shù)(不能使用固定值),防止被攻擊,具體使用后邊會(huì)說(shuō),在密鑰交換過(guò)程中是一個(gè)很重要的參數(shù);
CipherSuite
cipherSuite定義的就是后續(xù)要使用的加密組件,下面我們用其中的?TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384?來(lái)講下這一長(zhǎng)串加密定義是什么意思;
首先是TLS是固定的,表示這是TLS加密套件;
然后是?ECDHE_RSA?,這個(gè)代表的是后續(xù)使用?ECDHE?密鑰交換算法,?RSA?表示證書(shū)密鑰算法是用的RSA,這里 要特別說(shuō)下?ECDHE?密鑰交換算法,很多人腦子里一想到HTTPS估計(jì)第一時(shí)間想到的就是公鑰加密一個(gè)對(duì)稱加密的密鑰然后私鑰解密,這樣來(lái)交換對(duì)稱加密的密鑰,但 是這種算法沒(méi)有前向安全性,什么是前向安全性呢?舉個(gè)例子,假如你用的這種算法來(lái)交換密鑰,雖然當(dāng)時(shí)可能無(wú)法破解,因?yàn)閷?duì)稱加密密鑰被RSA公鑰加密了,沒(méi)有私鑰 沒(méi)辦法解密,但是別人可以將加密數(shù)據(jù)先保存下來(lái),等到某天,如果這個(gè)網(wǎng)站的RSA私鑰泄露了,甚至網(wǎng)站開(kāi)發(fā)者被政府要求主動(dòng)提供私鑰,這時(shí)開(kāi)發(fā)者一般是無(wú)法拒絕 的,而一旦這個(gè)私鑰泄露,別人就能解密之前你的加密數(shù)據(jù)了,一旦密鑰泄露,之前所有的加密數(shù)據(jù)都將不安全,這個(gè)就是沒(méi)有前向安全性,而ECDH(和ECDHE原理上 是一樣的,不過(guò)有些細(xì)節(jié)不一樣)密鑰交換算法就是解決這個(gè)問(wèn)題的;
然后是AES_256_GCM,這個(gè)就是最終我們要使用的對(duì)稱加密算法了,AES_256_GCM就 表示使用256bit密鑰的AES算法,GCM是AES的一種模式(建議使用這個(gè)模 式的AES,其他模式的AES有潛在問(wèn)題,已經(jīng)不太安全了),用于對(duì)加密內(nèi)容生成摘要的處理,因?yàn)閮H僅加密的話只能保證不被別人查看,但是無(wú)法保證不被篡改(就 是別 人拿到一串密文后,隨機(jī)將其中的一個(gè)bit從0標(biāo)為1或者從1變?yōu)?,如果運(yùn)氣夠好正好 修改后解密出來(lái)的內(nèi)容也是有含義的、我們也能消費(fèi),這樣就會(huì)導(dǎo)致一 些問(wèn) 題,而且我們還無(wú)從得知消息是否被篡改),所以需要加一個(gè)摘要,這樣一旦消息被篡改,因 為 攻擊者無(wú)法生成正確的摘要,所以我們只要驗(yàn)證摘要就能判斷 出來(lái) 消息是被篡改過(guò)的,從而可以避免被攻擊;
最后就是SHA384了,這是一個(gè)MAC算法,握手過(guò)程中密鑰交換和最后的finish消息會(huì)用到;
extension
擴(kuò)展中有幾個(gè)比較重要的擴(kuò)展,最終是會(huì)影響握手的,例如elliptic_curves和ec_point_formats(這個(gè)擴(kuò)展值是固定的)這兩個(gè)擴(kuò)展,如果我們選用ECC相關(guān) 的密鑰交換算法(例如ECDH),就必須有這個(gè)擴(kuò)展, 告訴對(duì)方我們選用的曲線ID,還有extended_master_secret這個(gè)擴(kuò)展,如果有這個(gè)擴(kuò)展,那么密鑰交換的 過(guò)程中一些密鑰生成細(xì)節(jié)將會(huì)更改,如果不正確的設(shè)置 或者不正確的消費(fèi)將會(huì)導(dǎo)致通信雙方無(wú)法協(xié)商出一致的密鑰最終導(dǎo)致握手失敗;
結(jié)束
本文將clientHello包進(jìn)行了一個(gè)簡(jiǎn)單的分析,同時(shí)對(duì)里邊需要關(guān)注的點(diǎn)進(jìn)行了簡(jiǎn)單的說(shuō)明,可以自己嘗試抓個(gè)包看看,熟悉下工具,也熟悉下抓包內(nèi)容;
聯(lián)系我
作者微信:JoeKerouac
微信公眾號(hào)(文章會(huì)第一時(shí)間更新到公眾號(hào)):Java初學(xué)者
GitHub:https://github.com/JoeKerouac
參考文獻(xiàn)
TLS1.2定義:https://tools.ietf.org/html/rfc5246
