為了搶口罩,我竟然把 https 的原理整明白了
疫情當(dāng)下,口罩難搶啊,沒有口罩的我不能出門。在 52 破解上看到了一個(gè)口罩查詢余量的軟件。
軟件類似這樣子:
我用這軟件蹲點(diǎn)搶來好久,也沒搶到。于是我尋思著,能不能把這個(gè)軟件的口罩消息來源給搞到。由于是一枚菜雞 web 狗,俺也不會(huì)逆向。通過 wireshark 來抓請(qǐng)求看看他到底是咋弄的。
看他軟件上的提示,是每隔 5s 就請(qǐng)求一次數(shù)據(jù)。由于 wireshark 抓包的數(shù)據(jù)是抓這個(gè)網(wǎng)卡的全部流量,分析起來比較多。打開 wireshark,抓了一會(huì)包就停了沒必要太久。不然會(huì)很多其他的流量請(qǐng)求。
可以看到居多數(shù)給 27.124.36.8 這個(gè) IP 發(fā)包,我日還是 https,這可咋整。沒有密鑰咋解密呢。嗯,雖然解不開數(shù)據(jù)包,不知道他以什么樣子的參數(shù)去發(fā)送,但是我們能看到服務(wù)器的證書信息。
發(fā)現(xiàn)了一個(gè) app.tonystark.io
僅僅是找到了服務(wù)器的地址,具體的口罩信息的請(qǐng)求方式,我們還是不知道。
從上面 wireshark 的流量,我們可以知道程序與服務(wù)器之間的通信是使用 https 來連接,在解密之前我們先來學(xué)一下 https 的原理吧。
一、Https 原理學(xué)習(xí)
https 與 http 相比,僅僅多了一層的 tls:
1. 為什么要加入這一層tls安全層呢?
是因?yàn)樽畛醯?HTTP 存在下面三個(gè)問題:
- 數(shù)據(jù)在裸奔。數(shù)據(jù)以明文的方式傳播
 - 無法驗(yàn)證通信雙方的身份
 - 無法防止數(shù)據(jù)被篡改
 
我們先來解決第一個(gè)問題,如何給數(shù)據(jù)加密?
- 密碼學(xué)加密方式只有對(duì)稱密碼和非對(duì)稱密碼
 - 對(duì)稱密碼:加密的加密和解密使用同一密鑰。
 
從流程圖中得到,這種加密方式在雙方通信時(shí)候需要預(yù)先準(zhǔn)備好密鑰。但是服務(wù)器和瀏覽器之間傳遞密鑰的過程被人監(jiān)聽,相當(dāng)于明文傳輸。倘若預(yù)先把密鑰保存在本地,到需要建立連接在取出,那么瀏覽器需要預(yù)存好世界上所以的 HTTPS 網(wǎng)站的密鑰,顯然不現(xiàn)實(shí)。
非對(duì)稱密碼:公鑰加密,私鑰解密
這種加密方式, 也稱為非對(duì)稱密鑰加密,使用一對(duì)密鑰用于加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發(fā)送方獲得接收方的公開密鑰之后,就可以使用公開密鑰進(jìn)行加密,接收方收到通信內(nèi)容后使用私有密鑰解密。因?yàn)楣€加密,私鑰解密,即使傳輸中的公鑰被監(jiān)聽了,也解不開傳輸?shù)牧髁?。但是僅僅是客戶端到服務(wù)器這條傳輸鏈路保證了傳輸?shù)陌踩敲丛趺幢WC服務(wù)端下行到客戶端這條鏈路的安全呢?
HTTPS 采用混合的加密機(jī)制,使用公開密鑰加密用于傳輸對(duì)稱密鑰,之后使用對(duì)稱密鑰加密進(jìn)行通信。
首先 Client 發(fā)起想要連接 Server,則會(huì)發(fā)送 ClientHello,這個(gè) Hello 信息標(biāo)識(shí)就是 Client 最高支持的 TLS 版本,支持的密碼套件,Session 信息以及壓縮算法。
而 Server 收到 Client 的請(qǐng)求后,會(huì)發(fā)送與協(xié)商確定 Client 的密碼套件,同時(shí)會(huì)發(fā)送 Server Certificate 證書信息和服務(wù)器公鑰。
Client 收到 ServerHello 后,會(huì)驗(yàn)證 Server 的證書信息是否合法,如果合法,則產(chǎn)生隨機(jī)碼(這一步又涉及到TLS的密鑰計(jì)算,太過復(fù)雜了,大家有興趣可以自己去查閱),作為對(duì)稱密鑰加密密鑰,對(duì)隨機(jī)碼使用接收到的服務(wù)器公鑰進(jìn)行加密。
大概的流程圖就是這樣子,不同的 TLS 版本流程很不一樣。
下面我用 wireshark 來抓一次 csdn 的 https 連接請(qǐng)求。
首先先看 ClientHello,TLS 版本信息,Session,以及支持的密碼套件
隨后的 ServerHello,不難發(fā)現(xiàn)選擇了 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 的加密方法
可以看到,ServerHello 后面還跟著一個(gè)數(shù)據(jù)包。其中有三個(gè)關(guān)鍵字:Certificate 、Certificate Status 、Server Key Exchange
Certificate 就是證書信息:
從數(shù)據(jù)包可以看出是由 www.digicert.com 簽發(fā),并且采用 sha256WithRSAEncryption 進(jìn)行簽名
Certificate Status 則是證書的狀態(tài)信息,包含證書的有效期至
最后 Server Key Exchange 則是 Server 的 Public Key 了
由于協(xié)商出來的是 ECDHE 密鑰協(xié)商算法 ,所以 Server 把 ECDH 的參數(shù)和公鑰發(fā)給 Client。這里的 ECDH 曲線是 secp256r1,公鑰是 047b36092eb10...............
至此 ServerHello 結(jié)束。
由于是 ECDHE 協(xié)商算法,所以 Client 需要發(fā)送 ECC DH 公鑰,也有三個(gè)關(guān)鍵字:
Client Key Exchange 不必多說,是 Client 發(fā)送的 ECCDH 公鑰,其值是 04acb6e.....
ChangeCipherSpec 消息結(jié)構(gòu)很簡單,發(fā)送這條消息是為了告訴 Server ,Client 可以使用 TLS 記錄層協(xié)議進(jìn)行密碼學(xué)保護(hù)了。第一條進(jìn)行密碼學(xué)保護(hù)的消息是 Finished 消息。
后面兩個(gè)數(shù)據(jù)包則是流量控制。有助于確保只傳播接受者需要使用的數(shù)據(jù)數(shù)據(jù)。之后就是新的 session 建立,Server 返回 ChangeCipherSpec 和 finish。這里還有一部分的 TLS 會(huì)話復(fù)用機(jī)制。請(qǐng)讀者自行查閱。
目前為止 https 整個(gè)連接已經(jīng)建立起來了。
現(xiàn)在我們已經(jīng)解決了Https如何給數(shù)據(jù)加密的過程。
2. 現(xiàn)在來看第二個(gè)問題:如何驗(yàn)證通信雙方的身份?
在上面的 wireshark 流量分析中,我們可以看到一個(gè) Certificate 的身影。沒錯(cuò), HTTPS 通過使用 證書 來對(duì)通信方進(jìn)行認(rèn)證。
數(shù)字證書認(rèn)證機(jī)構(gòu)(CA,Certificate Authority)是客戶端與服務(wù)器雙方都可信賴的第三方機(jī)構(gòu)。服務(wù)器的運(yùn)營人員向 CA 提出公開密鑰的申請(qǐng),CA 在判明提出申請(qǐng)者的身份之后,會(huì)對(duì)已申請(qǐng)的公開密鑰做數(shù)字簽名,然后分配這個(gè)已簽名的公開密鑰,并將該公開密鑰放入公開密鑰證書后綁定在一起。
進(jìn)行 HTTPS 通信時(shí),服務(wù)器會(huì)把證書發(fā)送給客戶端,客戶端取得其中的公開密鑰之后,先進(jìn)行驗(yàn)證,如果驗(yàn)證通過,就可以開始通信。
舉個(gè)例子
上圖中的步驟 1、2、3、4 并不是每次都需要這樣請(qǐng)求。1、2、3 步只需要在注冊(cè)新的公鑰的時(shí)候才會(huì)進(jìn)行。第四步僅在第一次需要使用公鑰密碼的時(shí)候需要,之后保存到了電腦中,就不用每次都請(qǐng)求公鑰了。
網(wǎng)站在使用HTTPS前,需要向“CA機(jī)構(gòu)”申請(qǐng)頒發(fā)一份數(shù)字證書,數(shù)字證書里有證書持有者、證書持有者的公鑰等信息,服務(wù)器把證書傳輸給瀏覽器,瀏覽器從證書里取公鑰就行了,證書就如身份證一樣,可以證明“該公鑰對(duì)應(yīng)該網(wǎng)站”
二、那么怎么認(rèn)證數(shù)據(jù)的完整性?舉個(gè)例子 :
A 向 B 匯錢 100 萬元。如果攻擊者從中攻擊,篡改這條消息,就可能變成 A 向攻擊者匯錢 1000 萬元。這里針對(duì)匯款消息。如何保證兩個(gè)問題:消息的 “完整性” 和 “認(rèn)證” 。
這時(shí)候可以用到數(shù)字簽名技術(shù),相當(dāng)于現(xiàn)實(shí)生活的蓋章。數(shù)字簽名可以識(shí)別篡改、偽裝、防止抵賴。
非對(duì)稱密鑰是公鑰加密,私鑰解密。而數(shù)字簽名是公鑰解密,私鑰加密。看一個(gè)流程
為了防止消息被篡改和被偽造,使用數(shù)字簽名技術(shù),服務(wù)端使用私鑰對(duì)消息的 hash 進(jìn)行加密,再把 hash 和簽名發(fā)送給客戶端,隨后客戶端利用公鑰進(jìn)行解密,比對(duì)傳輸?shù)?hash 是否一致。如果一致就證明消息未被篡改和偽造。
我們都知道,指紋是一個(gè)人獨(dú)一無二的東西,能通過它找他對(duì)應(yīng)的唯一一個(gè)人。而消息的指紋就是密碼學(xué)中的單向散列函數(shù) (Hash)。每一個(gè)消息都有其對(duì)應(yīng)的 Hash,如果消息發(fā)生了變換,其 hash 也會(huì)隨之變換。
消息的完整性,就叫消息的一致性,這個(gè)可以用消息指紋來判斷,通過對(duì)比單向散列函數(shù)的 hash 值來判斷這條消息的完整性,有沒有被篡改。
消息的認(rèn)證,指的是,消息是否來自正確的發(fā)送者。如果確認(rèn)匯款請(qǐng)求確實(shí)來自 A,就相當(dāng)于對(duì)消息進(jìn)行了認(rèn)證,代表消息沒有被偽裝。
好了 Https 大概完成了 Http 不曾完成的三個(gè)使命。想必看完你也大概了解了 Https 是怎么實(shí)現(xiàn)它所說的安全的。
三、怎么才能夠?qū)α髁窟M(jìn)行解密?
網(wǎng)上搜索大多都是兩種解法,一種是導(dǎo)入 RSA 私鑰進(jìn)入 wireshark。第二種是配置 SSLKEYLOGFILE。
第一種:導(dǎo)入 RSA 私鑰進(jìn)入 wireshark
實(shí)現(xiàn)過程:
1. 拿到百度的服務(wù)器證書
使用 fiddler 的中間人代理技術(shù)拿到含有私鑰的服務(wù)器證書。
- 打開 fiddler 并啟用 https 代理服務(wù)
 - 用配置了 fiddler 代理的瀏覽器訪問百度
 - 運(yùn)行 “certmgr.msc”打開證書管理器
 - 從 Personal/Certificates 目錄下找到 *.baidu.com 的證書,右鍵所有任務(wù)-導(dǎo)出
 
2、取出證書中的私鑰
使用 openssl 取出私鑰。
1) 將 pfx 證書轉(zhuǎn)為 pem 證書
命令行:
- openssl pkcs12 -in <pfx證書路徑> -nodes -out <輸出的pem證書路徑(.pem)>
 
2) 從 pem 證書中取出私鑰
命令行:
- openssl rsa -in <pem證書路徑> -out <輸出的私鑰文件路徑(.key)>
 
3) 點(diǎn)擊編輯——>首選項(xiàng)——>協(xié)議——>SSL(有的版本只有 TLS),導(dǎo)入 RSA key:
導(dǎo)入服務(wù)器證書:
點(diǎn)擊 ok 后,Wireshark 會(huì)對(duì)捕獲的報(bào)文進(jìn)行解密:
這種方法僅僅對(duì)于使用 RSA 的密鑰交換有用,在知曉了 RSA 密鑰,就可以導(dǎo)入 wireshark 來解密流量。但是目前大多數(shù)的 HTTPS 網(wǎng)站都是采用 DH 密鑰交換。在此說明一下 RSA 和 DH 的區(qū)別。先看這個(gè)兩個(gè)的過程。
ssl_handshake_rsa:
- Client Hello,包含協(xié)議版本、客戶端 random、密碼套件列表
 - Server Hello,服務(wù)器“hello”消息包含服務(wù)器隨機(jī)、服務(wù)器選擇的密碼套件和服務(wù)器的證書
 - Client Key Exchange Client 驗(yàn)證證書后,客戶端創(chuàng)建一個(gè)隨機(jī)的 pre-master secret。并使用公鑰加密發(fā)送 之后服務(wù)器收到加密的 pre-master secret 會(huì)使用私鑰進(jìn)行解密。所以,我們知道私鑰,就可以導(dǎo)入 wireshark ,解出 pre-master secret 來解密流量。
 
ssl_handshake_diffie_hellman:
- Client Hello,包含協(xié)議版本、客戶端 random、密碼套件列表
 - Server Hello,服務(wù)器“hello”消息包含服務(wù)器隨機(jī)、服務(wù)器選擇的密碼套件和服務(wù)器的證書
 - Server Key Exchange 緊跟著 Server Hello,為了啟動(dòng) DH 交換,服務(wù)器會(huì)發(fā)送 Diffie-Hellman 參數(shù)和簽名
 - Client Key Exchange 客戶端會(huì)驗(yàn)證服務(wù)器的證書。然后會(huì)向服務(wù)器發(fā)送 DH 參數(shù)。
 
注:整個(gè)過程不存在密鑰的交換,客戶端服務(wù)端可以通過 DH 參數(shù)來計(jì)算 pre-master secret。
對(duì)于這種情況,由于 Premaster Secret 無需交換,中間人就算有私鑰也無法獲得 Premaster Secret 和 Master Secret。也就是說 Wireshark 無法通過配置 RSA Private Key 的方式解密「使用 ECDHE 進(jìn)行密鑰交換」的加密流量。
第二種 SSLKEYLOGFILE
在系統(tǒng)環(huán)境變量加入SSLKEYLOGFILE這個(gè)變量,并選擇導(dǎo)出目錄
Firefox 和 Chrome 都會(huì)在系統(tǒng)環(huán)境變量存在 SSLKEYLOGFILE 文件路徑時(shí),將每個(gè) HTTPS 連接產(chǎn)生的 Premaster Secret 或 Master Secret 存下來。有了這個(gè)文件,Wireshark 就可以輕松解密 HTTPS 流量
然后打開 wireshark,ctrl+shift+P 在 Protocols 選擇 TLS 協(xié)議,并導(dǎo)入即可
即可解除加密
可是這兩種對(duì)我都沒用啊。這個(gè)是程序與服務(wù)器連接,弄不出來 HTTPS 連接產(chǎn)生的 Premaster Secret 或 Master Secret。而且每次連接的 Secret 都是隨機(jī)的啊。
下面就要說到另外一種。學(xué)安全的大家都知道,burp 在抓取 https 流量的時(shí)候,需要信任 burp 的證書。那么大家可想過,這是為何?
burp,Charles,fildder這些抓包工具,主要是利用了中間人攻擊的思想,
正常的通信只有 Client,Server。
中間人攻擊的時(shí)候,加入了一個(gè)中間方。Client 信任中間方的證書后,就會(huì)和中間方進(jìn)行通信。然后中間方拿到 Client 發(fā)送的請(qǐng)求,就會(huì)偽裝成 Client 對(duì)服務(wù)方建立請(qǐng)求。監(jiān)聽雙方的通信。
所以只要 Client 信任了 burp 的證書,Client 會(huì)和 burp 建立 Https 連接。burp 收到 Client 的請(qǐng)求后,則會(huì)去和 Server 建立連接,偽造 Client 通信。
想必看到這里你們腦海中浮現(xiàn)一個(gè)疑問:不是說 Https 可以驗(yàn)證通信雙方的身份?
是這樣子的。Https 有單端驗(yàn)證和雙端驗(yàn)證
圖片來源:https://www.jianshu.com/p/a2a7ddce7075
一般 Web 應(yīng)用都是采用 SSL 單向認(rèn)證的,原因很簡單,用戶數(shù)目廣泛,且無需在通訊層對(duì)用戶身份進(jìn)行驗(yàn)證,一般都在應(yīng)用邏輯層來保證用戶的合法登入。但如果是企業(yè)應(yīng)用對(duì)接,情況就不一樣,可能會(huì)要求對(duì)客戶端(相對(duì)而言)做身份驗(yàn)證。這時(shí)就需要做 SSL 雙向認(rèn)證。
- 客戶端向服務(wù)端發(fā)送SSL協(xié)議版本號(hào)、加密算法種類、隨機(jī)數(shù)等信息。
 - 服務(wù)端給客戶端返回SSL協(xié)議版本號(hào)、加密算法種類、隨機(jī)數(shù)等信息,同時(shí)也返回服務(wù)器端的證書,即公鑰證書
 - 客戶端使用服務(wù)端返回的信息驗(yàn)證服務(wù)器的合法性,包括:證書是否過期、發(fā)型服務(wù)器證書的CA是否可靠、返回的公鑰是否能正確解開返回證書中的數(shù)字簽名、 服務(wù)器證書上的域名是否和服務(wù)器的實(shí)際域名相匹配、驗(yàn)證通過后,將繼續(xù)進(jìn)行通信,否則,終止通信
 - 客戶端向服務(wù)端發(fā)送自己所能支持的對(duì)稱加密方案,供服務(wù)器端進(jìn)行選擇
 - 服務(wù)器端在客戶端提供的加密方案中選擇加密程度最高的加密方式。
 - 服務(wù)器將選擇好的加密方案通過明文方式返回給客戶端
 - 客戶端接收到服務(wù)端返回的加密方式后,使用該加密方式生成產(chǎn)生隨機(jī)碼,用作通信過程中對(duì)稱加密的密鑰,使用服務(wù)端返回的公鑰進(jìn)行加密,將加密后的隨機(jī)碼發(fā)送至服務(wù)器
 - 服務(wù)器收到客戶端返回的加密信息后,使用自己的私鑰進(jìn)行解密,獲取對(duì)稱加密密鑰。在接下來的會(huì)話中,服務(wù)器和客戶端將會(huì)使用該密碼進(jìn)行對(duì)稱加密,保證通信過程中信息的安全。
 
- 客戶端向服務(wù)端發(fā)送SSL協(xié)議版本號(hào)、加密算法種類、隨機(jī)數(shù)等信息。
 - 服務(wù)端給客戶端返回SSL協(xié)議版本號(hào)、加密算法種類、隨機(jī)數(shù)等信息,同時(shí)也返回服務(wù)器端的證書,即公鑰證書
 - 客戶端使用服務(wù)端返回的信息驗(yàn)證服務(wù)器的合法性,包括:證書是否過期、發(fā)型服務(wù)器證書的CA是否可靠、返回的公鑰是否能正確解開返回證書中的數(shù)字簽名、服務(wù)器證書上的域名是否和服務(wù)器的實(shí)際域名相匹配、驗(yàn)證通過后,將繼續(xù)進(jìn)行通信,否則,終止通信
 - 服務(wù)端要求客戶端發(fā)送客戶端的證書,客戶端會(huì)將自己的證書發(fā)送至服務(wù)端
 - 驗(yàn)證客戶端的證書,通過驗(yàn)證后,會(huì)獲得客戶端的公鑰
 - 客戶端向服務(wù)端發(fā)送自己所能支持的對(duì)稱加密方案,供服務(wù)器端進(jìn)行選擇
 - 服務(wù)器端在客戶端提供的加密方案中選擇加密程度最高的加密方式
 - 將加密方案通過使用之前獲取到的公鑰進(jìn)行加密,返回給客戶端
 - 客戶端收到服務(wù)端返回的加密方案密文后,使用自己的私鑰進(jìn)行解密,獲取具體加密方式,而后,產(chǎn)生該加密方式的隨機(jī)碼,用作加密過程中的密鑰,使用之前從服務(wù)端證書中獲取到的公鑰進(jìn)行加密后,發(fā)送給服務(wù)端
 - 服務(wù)端收到客戶端發(fā)送的消息后,使用自己的私鑰進(jìn)行解密,獲取對(duì)稱加密的密鑰,在接下來的會(huì)話中,服務(wù)器和客戶端將會(huì)使用該密碼進(jìn)行對(duì)稱加密,保證通信過程中信息的安全
 
工具是:Burp+Proxiey
設(shè)置好規(guī)則
想要的內(nèi)容就收到了:
總結(jié)
為了搶個(gè)口罩也是不容易,硬生生的把 HTTPS 原理給整明白了,學(xué)無止境,希望對(duì)大家有所幫助。


















































 
 
 







 
 
 
 