看完還不懂HTTPS我直播吃翔

本文首發(fā)于我的個(gè)人技術(shù)博客看完還不懂HTTPS我直播吃翔

存在即合理

http是非常常見的應(yīng)用層協(xié)議,是超文本傳輸協(xié)議的簡(jiǎn)稱,其傳輸?shù)膬?nèi)容都是明文的。在這個(gè)混亂的世界,明文傳輸信息想想就可怕,網(wǎng)絡(luò)“小混混”的手段遠(yuǎn)比我們這些凡人高明得多,他們有一萬種方式劫持,篡改我們的數(shù)據(jù)。對(duì)于一個(gè)網(wǎng)站或者服務(wù),如果你給你的用戶兩個(gè)選擇:

  1. 通訊數(shù)據(jù)明文傳輸,速度快;
  2. 通訊數(shù)據(jù)加密傳輸,但是速度可能會(huì)稍微慢一點(diǎn).

我想,只要腦袋沒有長(zhǎng)歪的用戶都寧愿犧牲一點(diǎn)速度去換取數(shù)據(jù)傳輸?shù)陌踩?/p>

這樣,https的存在就具備了合理性,https中的s表示SSL或者TLS,就是在原h(huán)ttp的基礎(chǔ)上加上一層用于數(shù)據(jù)加密、解密、身份認(rèn)證的安全層。

一層層揭開HTTPS神秘面紗

本文試圖通過層層漸進(jìn)方式來通俗的闡述https的原理,若有錯(cuò)誤,歡迎大家指正。

雖然要層層漸進(jìn),但是我們不妨先奉上剛畫好的還熱乎著的https通信完整流程圖:


從上圖可以看到,右邊有一堆鑰匙,一看到鑰匙我們就能想到這個(gè)過程免不了加密。另外,那些鑰匙長(zhǎng)得還不一樣,有些只有一把,有些是一對(duì),嗯,是的,你看得真仔細(xì)。

好的,扯遠(yuǎn)了,現(xiàn)在開始層層漸進(jìn)。

第一層(安全傳輸數(shù)據(jù))

假如我們要實(shí)現(xiàn)一個(gè)功能:一個(gè)用戶A給一個(gè)用戶B發(fā)消息,但是要保證這個(gè)消息的內(nèi)容只能被A和B知道,其他的無論是墨淵上神還是太上老君都沒辦法破解或者篡改消息的內(nèi)容。

如上圖,需求就是這么簡(jiǎn)單,A給B發(fā)一條消息,因?yàn)楸容^私密,不想被其他人看到。

由于消息不想被其他人看到,所以我們自然而然就會(huì)想到為消息加密,并且只有A和B才有解密的密鑰。這里需要考慮幾點(diǎn):

  1. 使用什么加密方式?
  2. 密鑰怎么告知對(duì)方?

對(duì)于第一個(gè)問題,加密算法分為兩類:對(duì)稱加密和非對(duì)稱加密,這里我們選擇對(duì)稱機(jī)密,原因有如下幾個(gè):

  1. 對(duì)稱加密速度快,加密時(shí)CPU資源消耗少;
  2. 非對(duì)稱加密對(duì)待加密的數(shù)據(jù)的長(zhǎng)度有比較嚴(yán)格的要求,不能太長(zhǎng),但是實(shí)際中消息可能會(huì)很長(zhǎng)(比如你給你女朋友發(fā)情書),因此非對(duì)稱加密就滿足不了;

對(duì)于第二個(gè)問題,這是導(dǎo)致整個(gè)https通信過程很復(fù)雜的根本原因。
如果A或B直接把他們之間用于解密的密鑰通過互聯(lián)網(wǎng)傳輸給對(duì)方,那一旦密鑰被第三者劫持,第三者就能正確解密A,B之間的通信數(shù)據(jù)。

第二層(安全傳輸密鑰)

通過第一層的描述,第二層需要解決的問題是:安全地傳輸A,B之間用于解密數(shù)據(jù)的密鑰。

因?yàn)槿绻麄鬏斶^程中這把密鑰被第三者拿到了,就能解密傳通信數(shù)據(jù),所以,這把密鑰必須得加密,就算第三者劫持到這把加密過的密鑰,他也不能解密,得到真正的密鑰。

這里有一個(gè)問題,那要用什么方式加密這把密鑰呢?如果使用對(duì)稱加密,那這個(gè)對(duì)稱加密的密鑰又怎么安全地告訴對(duì)方呢?完了,陷入死循環(huán)了.... 所以,一定不能用對(duì)稱加密

那就是用非對(duì)稱加密咯,那如何應(yīng)用非對(duì)稱加密來加密那把密鑰呢?

考慮如下方式:


  1. 客戶端: 我要發(fā)起HTTPS請(qǐng)求,麻煩給我一個(gè)非對(duì)稱加密的公鑰;
  2. 服務(wù)器: (生成一對(duì)非對(duì)稱加密的密鑰對(duì),然后把公鑰發(fā)給客戶端),接著,這是公鑰;
  3. 客戶端:(收到公鑰,生成一個(gè)隨機(jī)數(shù),作為上圖中那一把密鑰,用剛才收到的公鑰加密這個(gè)密鑰,然后發(fā)給服務(wù)器)這是我剛生成的加密過的密鑰;
  4. 服務(wù)器:(收到加密后的密鑰,用本地的第一步自己生成的非對(duì)稱加密的私鑰解密,得到真正的密鑰);
  5. 現(xiàn)在,客戶端和服務(wù)器都知道了這把密鑰,就能愉快地用這個(gè)密鑰對(duì)稱加密數(shù)據(jù)...

分析一下上面步驟的可行性:

  • 上述步驟中最終用于加密數(shù)據(jù)的密鑰是客戶端生成并且用公鑰加密之后傳給服務(wù)器的,因?yàn)樗借€只有服務(wù)器才有,所以也就只有服務(wù)器才能解開客戶端上報(bào)的密鑰;
  • 要保證傳輸?shù)拿荑€只能被服務(wù)器解密,就得保證用于加密密鑰的公鑰一定是服務(wù)器下發(fā)的,絕對(duì)不可能被第三方篡改過;

因?yàn)檫€可能存在一種"中間人攻擊"的情況,如下圖:


感謝XngPro的指正,上圖第7步,應(yīng)該是『壞人用B私鑰解密得到K,然后使用A公鑰加密發(fā)給服務(wù)器』

這種情況下,客戶端和服務(wù)器之間通信的數(shù)據(jù)就完全被壞人破解了。

第三層(安全傳輸公鑰)

從上一層可以知道,要保證數(shù)據(jù)的安全,就必須得保證服務(wù)器給客戶端下發(fā)的公鑰是真正的公鑰,而不是中間人偽造的公鑰。那怎么保證呢?

那就得引入數(shù)字證書了,數(shù)字證書是服務(wù)器主動(dòng)去權(quán)威機(jī)構(gòu)申請(qǐng)的,證書中包含了上一個(gè)圖中的加密過的A公鑰和權(quán)威機(jī)構(gòu)的信息,所以服務(wù)器只需要給客戶端下發(fā)數(shù)字證書即可?,F(xiàn)在流程圖如下:



那數(shù)字證書中的A公鑰是如何加密的呢?

答案是非對(duì)稱加密,只不過這里是使用只有權(quán)威機(jī)構(gòu)自己才有的私鑰加密。

等一下,既然A公鑰被權(quán)威機(jī)構(gòu)的私鑰加密了,那客戶端收到證書之后怎么解密證書中的A公鑰呢?需要有權(quán)威機(jī)構(gòu)的公鑰才能解密啊!那這個(gè)權(quán)威機(jī)構(gòu)的公鑰又是怎么安全地傳輸給客戶端的呢?感覺進(jìn)入了雞生蛋,蛋生雞的悖論了~~

別慌,答案是權(quán)威機(jī)構(gòu)的公鑰不需要傳輸,因?yàn)闄?quán)威機(jī)構(gòu)會(huì)和主流的瀏覽器或操作系統(tǒng)合作,將他們的公鑰內(nèi)置在瀏覽器或操作系統(tǒng)環(huán)境中。客戶端收到證書之后,只需要從證書中找到權(quán)威機(jī)構(gòu)的信息,并從本地環(huán)境中找到權(quán)威機(jī)構(gòu)的公鑰,就能正確解密A公鑰。

這樣就絕對(duì)安全了嗎?既然權(quán)威技能能給服務(wù)器簽發(fā)數(shù)字證書,那為什么就不可能給中間人簽發(fā)數(shù)字證書呢?畢竟賺錢的生意權(quán)威機(jī)構(gòu)也不會(huì)拒絕的呀。

試想一下:

服務(wù)器給客戶端下發(fā)數(shù)字證書時(shí)證書被中間人劫持了,中間人將服務(wù)器的證書替換成自己的證書下發(fā)給客戶端,客戶端收到之后能夠通過權(quán)威機(jī)構(gòu)的公鑰解密證書內(nèi)容(因?yàn)橹虚g人的證書也是權(quán)威機(jī)構(gòu)私鑰加密的),從而獲取公鑰,但是,這里的公鑰并不是服務(wù)器原本的A公鑰,而是中間人自己證書中的B公鑰。從第二層可知,如果不能保證客戶端收到的公鑰是服務(wù)器下發(fā)的,那整個(gè)通信數(shù)據(jù)的安全就沒法保證。簡(jiǎn)單總結(jié)就是證書被調(diào)包~

所以,還得保證客戶端收到的證書就是服務(wù)器下發(fā)的證書,沒有被中間人篡改過。

第四層(安全傳輸證書)

這一層,我們的任務(wù)是:保證客戶端收到的證書是服務(wù)器下發(fā)的證書,沒有被中間人篡改過。

所以,這里就有兩個(gè)需求:

  • 證明證書內(nèi)容沒有被第三方篡改過;
  • 證明證書是服務(wù)器下發(fā)的;

其實(shí)這些問題,數(shù)字證書本身已經(jīng)提供方案了,數(shù)字證書中除了包含加密之后的服務(wù)器公鑰,權(quán)威機(jī)構(gòu)的信息之外,還包含了證書內(nèi)容的簽名(先通過Hash函數(shù)計(jì)算得到證書數(shù)字摘要,然后用權(quán)威機(jī)構(gòu)私鑰加密數(shù)字摘要得到數(shù)字簽名),簽名計(jì)算方法以及證書對(duì)應(yīng)的域名。這樣一來,客戶端收到證書之后:

  • 使用權(quán)威機(jī)構(gòu)的公鑰解密數(shù)字證書,得到證書內(nèi)容(服務(wù)器的公鑰)以及證書的數(shù)字簽名,然后根據(jù)證書上描述的計(jì)算證書簽名的方法計(jì)算一下當(dāng)前證書的簽名,與收到的簽名作對(duì)比,如果一樣,表示證書一定是服務(wù)器下發(fā)的,沒有被中間人篡改過。因?yàn)橹虚g人雖然有權(quán)威機(jī)構(gòu)的公鑰,能夠解析證書內(nèi)容并篡改,但是篡改完成之后中間人需要將證書重新加密,但是中間人沒有權(quán)威機(jī)構(gòu)的私鑰,無法加密,強(qiáng)行加密只會(huì)導(dǎo)致客戶端無法解密,如果中間人強(qiáng)行亂修改證書,就會(huì)導(dǎo)致證書內(nèi)容和證書簽名不匹配。所以證書簽名就能判斷證書是否被篡改
  • 再考慮證書被掉包的情況:中間人同樣可以向權(quán)威機(jī)構(gòu)申請(qǐng)一份證書,然后在服務(wù)器給客戶端下發(fā)證書的時(shí)候劫持原證書,將自己的假證書下發(fā)給客戶端,客戶端收到之后依然能夠使用權(quán)威機(jī)構(gòu)的公鑰解密證書,并且證書簽名也沒問題。但是這個(gè)時(shí)候客戶端還需要檢查證書中的域名和當(dāng)前訪問的域名是否一致。如果不一致,會(huì)發(fā)出警告!

從上面的分析可以看到,數(shù)字證書中的信息確實(shí)能讓客戶端辨別證書的真?zhèn)巍?/p>

怎么樣?經(jīng)過這么幾句通俗的話,是不是對(duì)HTTPS的通信機(jī)制有了比較清晰的認(rèn)識(shí)了。當(dāng)然了,有一些可能是我胡扯的,不一定對(duì),大家多多指正!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容