What is HTTPS?
HTTPS = HTTP + SSL/TLS 。
SSL/TLS基于TCP缀台,工作在OSI七層模型中的表示層垄提,SSL不是簡(jiǎn)單地單個(gè)協(xié)議价捧,而是兩層協(xié)議:SSL記錄協(xié)議和高層協(xié)議(SSL握手協(xié)議枫慷,SSL修改密碼參數(shù)協(xié)議让蕾,SSL報(bào)警協(xié)議)。
HTTP與SSL/TLS協(xié)議組合使用的話(huà)或听,就可以加密HTTP的通信內(nèi)容探孝,解決HTTP通信不安全的問(wèn)題。
怎樣才是一次安全的通信?
- 傳輸?shù)膱?bào)文信息應(yīng)是被加密的神帅。
- 通信兩端的身份應(yīng)是被驗(yàn)證過(guò)的再姑,而不是攻擊者偽裝的。
- 報(bào)文的完整性應(yīng)得到驗(yàn)證找御,以防止中間人篡改報(bào)文信息元镀。
所以,HTTPS需要做到:
- 服務(wù)器認(rèn)證(客戶(hù)端知道它們是在與真正的而不是偽造的服務(wù)器通話(huà))霎桅;
- 客戶(hù)端認(rèn)證(服務(wù)器知道它們是在與真正的而不是偽造的客戶(hù)端通話(huà))栖疑;
- 完整性(客戶(hù)端和服務(wù)器的數(shù)據(jù)不會(huì)被修改);
- 加密(客戶(hù)端和服務(wù)器的對(duì)話(huà)是私密的滔驶,無(wú)需擔(dān)心被竊聽(tīng))遇革;
- 效率(一個(gè)運(yùn)行的足夠快的算法,以便低端的客戶(hù)端和服務(wù)器使用)揭糕;
- 普適性(基本上所有的客戶(hù)端和服務(wù)器都支持這些協(xié)議)萝快;
HTTPS協(xié)議的主要功能基本都依賴(lài)于TLS/SSL協(xié)議讹弯,提供了身份驗(yàn)證蔚出、信息加密和完整性校驗(yàn)的功能罢杉,可以解決HTTP存在的安全問(wèn)題蕴侣。
本小記主要記錄一下TLS/SSL協(xié)議的握手過(guò)程乱陡。
最復(fù)雜的地方:TLS/SSL握手
TLS握手主要可以分成三種流程:
- 單向驗(yàn)證,也就是只對(duì)服務(wù)器的身份進(jìn)行驗(yàn)證圈暗。
- 雙向驗(yàn)證康聂,對(duì)客戶(hù)端和服務(wù)器都進(jìn)行身份驗(yàn)證的握手啡邑。
- 簡(jiǎn)短握手产徊,用于恢復(fù)之前的回話(huà)昂勒。
單向驗(yàn)證握手過(guò)程:
握手過(guò)程圖,來(lái)自騰訊Bugly:
詳細(xì)步驟分析:
1.ClientHello:
客戶(hù)端發(fā)起請(qǐng)求舟铜,這條消息將客戶(hù)端的功能和首選項(xiàng)傳送給服務(wù)器戈盈。包含以下信息:
1. 客戶(hù)端支持的SSL的指定版本;
2. 加密組件(Cipher Suite)列表(所使用的加密算法密鑰長(zhǎng)度等)谆刨;
3. 支持的壓縮算法 compression methods 列表,用于后續(xù)的信息壓縮傳輸奕谭;
4. 隨機(jī)數(shù) random_C(隨機(jī)數(shù):1/3 共3個(gè),第1個(gè))痴荐,用于后續(xù)的密鑰的生成;
5. 擴(kuò)展字段 extensions血柳,支持協(xié)議與算法的相關(guān)參數(shù)以及其它輔助信息等;
抓包信息圖片,來(lái)自騰訊Bugly:
2. ServerHello
ServerHello消息將服務(wù)器選擇的連接參數(shù)傳送回客戶(hù)端生兆。也就是服務(wù)端在客戶(hù)端發(fā)送過(guò)來(lái)的加密組件列表壓縮方法列表選擇出了一種加密組件和壓縮方法难捌,發(fā)送回客戶(hù)端確認(rèn),還有一個(gè)隨機(jī)數(shù) random_S (隨機(jī)數(shù) 2/3)鸦难。
抓包信息圖片根吁,來(lái)自騰訊Bugly:
3.Server_Certificate 與 Sever_Hello_Done
服務(wù)器給客戶(hù)端發(fā)送證書(shū)報(bào)文,報(bào)文中包含了一個(gè)公鑰合蔽,這個(gè)公鑰稍被在客戶(hù)端用于加密一個(gè)隨機(jī)數(shù)击敌。報(bào)文中還有證書(shū)的簽名信息,用于確認(rèn)證書(shū)的合法性拴事。(客戶(hù)端讀取證書(shū)中的相關(guān)的明文信息沃斤,采用相同的散列函數(shù)計(jì)算得到信息摘要圣蝎,然后,利用對(duì)應(yīng)CA的公鑰解密簽名數(shù)據(jù)衡瓶,對(duì)比證書(shū)的簽名信息徘公,如果一致,則可以確認(rèn)證書(shū)的合法性哮针,即公鑰合法关面;)除了公鑰和簽名,證書(shū)報(bào)文還包含了申請(qǐng)者的組織信息和個(gè)人信息十厢、簽發(fā)機(jī)構(gòu)CA的信息等太、有效時(shí)間、證書(shū)序列號(hào)等信息的明文蛮放。證書(shū)=公鑰+申請(qǐng)者與頒發(fā)者信息+簽名缩抡;
server_hello_done,通知客戶(hù)端 server_hello 信息發(fā)送結(jié)束;
4.證書(shū)校驗(yàn)
客戶(hù)端接收到服務(wù)器發(fā)來(lái)的證書(shū)報(bào)文筛武,進(jìn)行證書(shū)校驗(yàn)缝其,合法性驗(yàn)證包括如下:
- [證書(shū)鏈]的可信性 trusted certificate path;
- 證書(shū)是否吊銷(xiāo) revocation,有兩類(lèi)方式離線 CRL 與在線 OCSP徘六,不同的客戶(hù)端行為會(huì)不同;
- 有效期 expiry date内边,證書(shū)是否在有效時(shí)間范圍;
- 域名 domain,核查證書(shū)域名是否與當(dāng)前的訪問(wèn)域名匹配待锈。
證書(shū)校驗(yàn)通過(guò)之后漠其,繼續(xù)下一步:
5. Client_Key_Exchange + Change_Cipher_Spec + Finished
- client_key_exchange:合法性驗(yàn)證通過(guò)之后,客戶(hù)端計(jì)算產(chǎn)生隨機(jī)數(shù)字 Pre-master(隨機(jī)數(shù) 3/3)竿音,并用證書(shū)公鑰加密和屎,發(fā)送給服務(wù)器;
此時(shí)客戶(hù)端已經(jīng)獲取全部的計(jì)算協(xié)商密鑰需要的信息:兩個(gè)明文隨機(jī)數(shù) random_C 和 random_S 與自己計(jì)算產(chǎn)生的 Pre-master,計(jì)算得到協(xié)商密鑰;
enc_key=Fuc(random_C, random_S, Pre-Master)
- ChangeCipherSpec:消息表明發(fā)送端已取得用以生成連接參數(shù)的足夠信息春瞬,已生成加密密鑰柴信,并且將切換到加密模式】砥客戶(hù)端和服務(wù)器在條件成熟時(shí)都會(huì)發(fā)送這個(gè)消息随常。注意:ChangeCipherSpec不屬于握手消息,它是另一種協(xié)議萄涯,只有一條消息绪氛,作為它的子協(xié)議進(jìn)行實(shí)現(xiàn)。
- Finished:消息意味著握手已經(jīng)完成涝影。結(jié)合之前所有通信參數(shù)的 hash 值與其它相關(guān)信息生成一段數(shù)據(jù)枣察,采用剛剛計(jì)算出來(lái)的還熱乎協(xié)商密鑰與之前約定算法進(jìn)行加密,然后發(fā)送給服務(wù)器用于數(shù)據(jù)與握手驗(yàn)證;
6. 服務(wù)端的ChangeCipherSpec + Finish
- 服務(wù)器用私鑰解密加密的 Pre-master 數(shù)據(jù),基于之前交換的兩個(gè)明文隨機(jī)數(shù) random_C 和 random_S序目,計(jì)算得到協(xié)商密鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
- 用這個(gè)剛計(jì)算出來(lái)的協(xié)商密鑰解密客戶(hù)端發(fā)送的 Finsh臂痕,驗(yàn)證數(shù)據(jù)和密鑰正確性;
- 驗(yàn)證通過(guò)之后,服務(wù)器同樣發(fā)送 ChangeCipherSpec 以告知客戶(hù)端后續(xù)的通信都采用協(xié)商的密鑰與算法進(jìn)行加密通信;
- 發(fā)送Finsh宛琅;
最后客戶(hù)端接收并計(jì)算所有接收信息的 hash 值刻蟹,并采用協(xié)商密鑰解密 Finsh逗旁,驗(yàn)證服務(wù)器發(fā)送的數(shù)據(jù)和密鑰嘿辟,驗(yàn)證通過(guò)則握手完成;
7.握手結(jié)束,開(kāi)始使用協(xié)商密鑰與算法進(jìn)行加密的HTTP通信片效。
雙向握手過(guò)程:
雙向驗(yàn)證相比單向驗(yàn)證红伦,多了一個(gè)驗(yàn)證客戶(hù)端合法性的步驟。這個(gè)步驟有兩條消息:
- Certificate Request :這條消息是服務(wù)器發(fā)送給客戶(hù)端淀衣,要求客戶(hù)端提供一份合法證書(shū)昙读。服務(wù)器應(yīng)該在ServerKeyExchange之后立即發(fā)送CertificateRequest消息。
- CertificateVerify : 這條消息是客戶(hù)端發(fā)送給服務(wù)器膨桥,來(lái)證明自己確實(shí)擁有客戶(hù)端證書(shū)的私鑰蛮浑。CertificateVerify緊跟在ClientKeyExchange之后被發(fā)送。
Android中的HTTPS
以O(shè)kHttp3.0為例
- 當(dāng)服務(wù)器的CA不被系統(tǒng)信任時(shí)只嚣,就會(huì)發(fā)生 SSLHandshakeException沮稚。這時(shí)可通過(guò)自定義TrustManager以實(shí)現(xiàn)自己的信任證書(shū)集合。
- 如域名驗(yàn)證失敗册舞,則自定義HostnameVerifier實(shí)現(xiàn)域名白名單蕴掏。
- 最后通過(guò)OkHttpClient.Builder()構(gòu)建相應(yīng)的配置。
參考代碼如下:
先記到這调鲸,待完善盛杰。。藐石。即供。