HTTPS 的工作原理
來源:stephanietang.github.io/2020/04/19/how-https-works/
我們?yōu)槭裁葱枰狧TTPS? HTTPS是什么?SSL/TLS是什么? SSL/TLS發(fā)展史 SSL/TLS的工作原理 參考
當(dāng)你打開瀏覽器,訪問某個(gè)網(wǎng)站,如果網(wǎng)址旁有個(gè)小鎖,代表訪問的網(wǎng)址是安全的,反之不安全。當(dāng)我們沒有看到那個(gè)小鎖的小圖標(biāo)的時(shí)候,需要提高警惕,不要隨意輸入個(gè)人重要的資料。所有的銀行和支付相關(guān)的網(wǎng)站都是100%使用HTTPS的。

我們?yōu)槭裁葱枰狧TTPS?
主要有三個(gè)原因:
保護(hù)隱私(Privacy):所有信息都是加密傳播,第三方無法竊聽數(shù)據(jù)。如果使用HTTP明文傳輸數(shù)據(jù)的話,很可能被第三方劫持?jǐn)?shù)據(jù),那么所輸入的密碼或者其他個(gè)人資料都被暴露在他人面前,后果可想而知。 數(shù)據(jù)完整性(Integraty):一旦第三方篡改了數(shù)據(jù),接收方會(huì)知道數(shù)據(jù)經(jīng)過了篡改,這樣便保證了數(shù)據(jù)在傳輸過程中不被篡改 —— 數(shù)據(jù)的完整性。 身份認(rèn)證(Identification):第三方不可能冒充身份參與通信,因?yàn)榉?wù)器配備了由證書頒發(fā)機(jī)構(gòu)(Certificate Authority,簡(jiǎn)稱CA)頒發(fā)的安全證書,可以證實(shí)服務(wù)器的身份信息,防止第三方冒充身份。(也有少數(shù)情況下,通信需要客戶端提供證書,例如銀行系統(tǒng),需要用戶在登錄的時(shí)候,插入銀行提供給用戶的USB,就是需要客戶端提供證書,用來驗(yàn)證客戶的身份信息。)
HTTPS是什么?SSL/TLS是什么?
HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議)是大家最熟悉的一種協(xié)議,它是一個(gè)用于傳輸超媒體文檔的協(xié)議,它位于OSI網(wǎng)絡(luò)協(xié)議模型的應(yīng)用層。但是它是明文傳輸協(xié)議,是非常不安全的,容易被人篡改和竊取數(shù)據(jù)。 SSL(Secure Socket Layer) —— 網(wǎng)景(Netscape)公司設(shè)計(jì)的主要用于web的安全傳輸協(xié)議。它位于TCP傳輸層協(xié)議和應(yīng)用層協(xié)議之間。(它沒有被劃分在OSI網(wǎng)絡(luò)協(xié)議模型中,且認(rèn)為它是應(yīng)用層的子層。) 眾所周知,網(wǎng)景公司20世紀(jì)90年代在和微軟的競(jìng)爭(zhēng)中最終敗下陣來,之后網(wǎng)景公司將SSL協(xié)議的管理權(quán)轉(zhuǎn)交給IETF(Internet Engineering Task Force, www.ietf.org)。于是IETF將SSL作了標(biāo)準(zhǔn)化,重新命名為TLS.xn--ietfssl%2Ctls-o68q04a8c50mt9nhxfc5e1qcb41ewo6bpjcqwqez6w/)(Transport Layer Security)。在1999年,TLS 1.0誕生了(其實(shí)也就是SSL 3.1)。 HTTPS(HyperText Transfer Protocol Secure)是建立在SSL/TLS協(xié)議之上,信息通信通過SSL/TLS進(jìn)行加密,最后一個(gè)S就是 Secure的縮寫,代表安全的意思,HTTPS = HTTP + SSL/TLS。

SSL/TLS發(fā)展史




實(shí)際上現(xiàn)代的瀏覽器已經(jīng)基本不使用SSL,使用的都是TLS,SSL 3.0于2015年已經(jīng)壽終正寢 —— 各大瀏覽器也不支持了。但是由于SSL這個(gè)術(shù)語存在的時(shí)間太長(zhǎng),很多地方還是廣泛的使用它,但是要清楚其實(shí)它說的是TLS。 有調(diào)查顯示現(xiàn)在絕大部分瀏覽器(> 99.5%)都使用TLS 1.2或者TLS 1.3。只有不足1%的瀏覽器仍然使用TLS 1.0或者TLS 1.1。 TLS 1.2仍然是主流協(xié)議(本文寫于2020年初),相信將來逐漸TLS 1.3將會(huì)作為主流協(xié)議。 很多瀏覽器將會(huì)開始不支持TLS 1.0和1.1: Google將在Chrome 72中不推薦使用TLS 1.0和1.1,而Chrome 81之后將會(huì)完全不支持。 Mozilla的Firefox,微軟的Edge和IE以及蘋果的Safari都會(huì)分別于2020年逐漸移除對(duì)TLS 1.0和1.1的支持。 那么一些還在使用TLS 1.0和1.1的網(wǎng)站就得被迫升級(jí)到TLS 1.2或者TLS 1.3。 要關(guān)閉瀏覽器對(duì)TLS 1.0和1.1的支持,可以在Internet選項(xiàng)中修改:

SSL/TLS的工作原理
需要理解SSL/TLS的工作原理,我們需要掌握加密算法。加密算法有兩種:對(duì)稱加密和非對(duì)稱加密:
對(duì)稱加密:通信雙方使用相同的密鑰進(jìn)行加密。特點(diǎn)是加密速度快,但是缺點(diǎn)是需要保護(hù)好密鑰,如果密鑰泄露的話,那么加密就會(huì)被別人破解。常見的對(duì)稱加密有AES,DES算法。 非對(duì)稱加密:它需要生成兩個(gè)密鑰:公鑰(Public Key)和私鑰(Private Key)。公鑰顧名思義是公開的,任何人都可以獲得,而私鑰是私人保管的。相信大多程序員已經(jīng)對(duì)這種算法很熟悉了:我們提交代碼到github的時(shí)候,就可以使用SSH key:在本地生成私鑰和公鑰,私鑰放在本地 .ssh目錄中,公鑰放在github網(wǎng)站上,這樣每次提交代碼,不用麻煩的輸入用戶名和密碼了,github會(huì)根據(jù)網(wǎng)站上存儲(chǔ)的公鑰來識(shí)別我們的身份。公鑰負(fù)責(zé)加密,私鑰負(fù)責(zé)解密;或者,私鑰負(fù)責(zé)加密,公鑰負(fù)責(zé)解密。這種加密算法安全性更高,但是計(jì)算量相比對(duì)稱加密大很多,加密和解密都很慢。常見的非對(duì)稱算法有RSA。
SSL/TLS是利用了對(duì)稱加密和非對(duì)稱加密的特點(diǎn)。先來看下整個(gè)SSL/TLS的握手過程,之后我們?cè)俜植襟E詳細(xì)解讀,每一步都干了些什么。

當(dāng)TCP建立連接之后,TLS握手的第一步由客戶端發(fā)起,發(fā)送 ClientHello的消息到服務(wù)器。ClientHello消息包含:
客戶端支持的SSL/TLS版本 客戶端支持的加密套件(Cipher Suites) 會(huì)話Id session id(如果有的值的話,服務(wù)器端會(huì)復(fù)用對(duì)應(yīng)的握手信息,避免短時(shí)間內(nèi)重復(fù)握手)隨機(jī)數(shù) client-random
“延伸閱讀:加密套件名如:“TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA256”,這么長(zhǎng)的名字看著有點(diǎn)暈吧,不用怕,其實(shí)它的命名非常規(guī)范,格式很固定。基本的形式是“密鑰交換算法-服務(wù)身份驗(yàn)證算法-對(duì)稱加密算法-握手校驗(yàn)算法”。握手過程中,證書簽名使用的RSA算法,如果證書驗(yàn)證正確,再使用ECDHE算法進(jìn)行密鑰交換,握手后的通信使用的是AES256的對(duì)稱算法分組模式是GCM。驗(yàn)證證書簽名合法性使用SHA256作哈希算法檢驗(yàn)。相關(guān)的算法的用處將在后文中詳解。
然后服務(wù)器端在收到這個(gè) ClientHello,從中選擇服務(wù)器支持的版本和套件,發(fā)送ServerHello消息:
服務(wù)器所能支持的最高SSL/TLS版本 服務(wù)器選擇的加密套件 隨機(jī)數(shù) server-random會(huì)話Id session id(用于下次復(fù)用當(dāng)前握手的信息,避免短時(shí)間內(nèi)重復(fù)握手。)
隨后服務(wù)器發(fā)送服務(wù)器的安全證書(含公鑰)。
如果需要客戶端也提供證書的話,還會(huì)發(fā)出客戶端證書請(qǐng)求(Client Certificate Request),只有少數(shù)金融機(jī)構(gòu)才需要客戶端也提供客戶端證書。
此后客戶端發(fā)送Server Hello Done消息表示Hello階段完成。
客戶端收到 ServerHello后,會(huì)對(duì)收到的證書進(jìn)行驗(yàn)證。
我們來看一下為什么可以通過CA(Certificate Authority,證書頒發(fā)機(jī)構(gòu))簽發(fā)的證書來確認(rèn)網(wǎng)站的身份?
當(dāng)我們安裝操作系統(tǒng)或者瀏覽器的時(shí)候,會(huì)安裝一組可信任的CA(根證書CA包括GlobalSign、GeoTrust、Verisign等)列表。根CA如GlobalSign就在我們的可信任的CA列表里,你的瀏覽器或者操作系統(tǒng)含有GlobalSign的公鑰。
先來看一下Google的證書,當(dāng)你訪問Google的時(shí)候,Google會(huì)發(fā)給你它的證書。證書中包含頒發(fā)機(jī)構(gòu)的簽名以及服務(wù)器的公鑰。

瀏覽器首先用哈希函數(shù)對(duì)明文信息的摘要做哈希得到一個(gè)哈希值(用到的就是證書中的簽名哈希算法SHA256),然后用根CA的公鑰對(duì)根證書的簽名作解密得到另一個(gè)哈希值(用到的算法就是RSA非對(duì)稱算法),如果兩個(gè)哈希值相等則說明證書沒有被篡改過。當(dāng)然還需校驗(yàn)證書中服務(wù)器名稱是否合法以及驗(yàn)證證書是否過期.

這樣就免受中間人攻擊了,因?yàn)榧偃缬兄虚g人修改了證書的內(nèi)容(如將證書中的公鑰替換成自己的公鑰),那么將獲得不同的哈希值,從而兩個(gè)哈希值不匹配導(dǎo)致驗(yàn)證失敗。如果要繞過這個(gè)機(jī)制,中間人必須要也替換簽名,使簽名也相匹配。而做到這一點(diǎn)就需要破解到了根證書的密鑰(而這是不可能的,中間人必然會(huì)失敗)。瀏覽器會(huì)出現(xiàn)以下畫面,告訴你正在遭受中間人攻擊,因?yàn)樽C書被篡改了:

那聰明的你肯定也想到了,如果你開發(fā)了一個(gè)系統(tǒng)還在測(cè)試階段,還沒有正式申請(qǐng)一張證書,那么你可以為服務(wù)器自簽名一張證書,然后將證書導(dǎo)入客戶端的CA信任列表中。
信任鏈機(jī)制

可以看到證書路徑是GlobalSign Root CA-R2 -> GTS CA 1O1->*.google.com。因?yàn)槲覀兊臑g覽器信任GlobalSign Root CA,根據(jù)信任鏈機(jī)制,你相信了根CA頒發(fā)的證書,也要相信它簽名的子CA頒發(fā)的證書,也要相信子CA簽名的子子CA的證書…而我們通過一級(jí)級(jí)的校驗(yàn),如果從根證書到最下層的證書都沒有被篡改過,我們就相信最下層的這個(gè)服務(wù)器證書是合法的。所以在這個(gè)機(jī)制中,你就需要無條件的相信根證書的頒發(fā)機(jī)構(gòu)。
如果通過驗(yàn)證,客戶端生成一個(gè)隨機(jī)數(shù)pre-master,用于密鑰交換過程。
密鑰交換過程:客戶端用第三步中服務(wù)器的證書中拿到服務(wù)器的公鑰,用這個(gè)公鑰加密(算法是加密套件中的密鑰交換算法,譬如 ECDHE算法)生成密文發(fā)送給服務(wù)器。客戶端用 server-random+client-random+pre-master一起計(jì)算出對(duì)稱密鑰master secret。服務(wù)器收到第四步的信息之后,用服務(wù)器的私鑰對(duì)密文進(jìn)行解密得到密鑰 pre-master。
因?yàn)橹挥蟹?wù)器有私鑰,可以針對(duì)客戶端發(fā)出的加密過的信息進(jìn)行解密得到pre-master,這樣就保證了只有服務(wù)器和客戶端知道pre-master。服務(wù)器端也可以用server-random + client-random + pre-master一起計(jì)算出對(duì)稱密鑰master secret。
現(xiàn)在客戶端和服務(wù)器均有密鑰master secret了,后面就可以用它來進(jìn)行加密和解密了。
“為什么不能只用一個(gè)
pre-master作為之后加密的對(duì)稱密鑰?雖然只有服務(wù)器有私鑰,能夠解密pre-master呀,但僅用它作為master secret是不夠安全的,這是因?yàn)橐苑揽蛻舳说?code style>pre-master并不是隨機(jī)數(shù)的情況。加上另外兩個(gè)隨機(jī)數(shù)client-random以及server-random(而這兩個(gè)隨機(jī)數(shù)和時(shí)間有相關(guān)性),這樣就能保證最后生成的master secret一定是隨機(jī)數(shù)。
客戶端用 master secret加密了一條握手完成的消息發(fā)送給服務(wù)器。服務(wù)器端也回發(fā)了一條用 master secret加密的握手完成的消息。當(dāng)兩方都收到對(duì)方發(fā)送的握手消息之后,也成功解密后,就可以用 master secret愉快的開始數(shù)據(jù)加密和解密了。
綜上,整個(gè)握手過程主要是通過一系列步驟通過非對(duì)稱加密的算法交換得到了master secret,這個(gè)步驟通常需要幾百毫秒,但是就是這一頓猛操作之后使得只有服務(wù)器和客戶端知道master secret。之后的通信又利用了高效的對(duì)稱算法對(duì)所有信息進(jìn)行加密和解密,雖然加密和解密也需要耗時(shí)耗流量,不過信息是完全不可能被別人篡改和破解的,這一點(diǎn)損耗還是值得的。
END
下方二維碼關(guān)注我

互聯(lián)網(wǎng)草根,堅(jiān)持分享技術(shù)、創(chuàng)業(yè)、產(chǎn)品等心得和總結(jié)~

點(diǎn)擊“閱讀原文”,領(lǐng)取 2020 年最新免費(fèi)技術(shù)資料大全




