HTTPS協議:點外賣的過程原來這麼複雜!

用HTTP協議,看個新聞還沒有問題,但是換到更加嚴肅的場景中,就存在很多的安全風險。例如你要下單做一次支付,如果還是使用普通的HTTP協議,那你很可能會被黑客盯上。

比如,你發送一個請求,說我要點個外賣,但是這個網絡包被截獲了,於是在服務器回覆你之前,黑客先假裝自己就是外賣網站,然後給你回覆一個假的消息說:“好啊好啊,來來來,銀行卡號、密碼拿來。”如果這時候你真把銀行卡密碼發給它,那你就真的上套了。

那怎麼解決這個問題呢?當然一般的思路就是加密。加密分爲兩種方式一種是對稱加密,一種是非對稱加密。

在對稱加密算法中,加密和解密使用的密鑰是相同的。也就是說,加密和解密使用的是同一個密鑰。因此,對稱加密算法要保證安全性的話,密鑰要做好保密。只能讓使用的人知道,不能對外公開。

在非對稱加密算法中,加密使用的密鑰和解密使用的密鑰是不相同的。一把是作爲公開的公鑰,另一把是作爲誰都不能給的私鑰。公鑰加密的信息,只有私鑰才能解密。私鑰加密的信息,只有公鑰才能解密。

因爲對稱加密算法相比非對稱加密算法來說,效率要高得多,性能也好,所以交互的場景下多用對稱加密。

對稱加密

假設你和外賣網站約定了一個密鑰,你發送請求的時候用這個密鑰進行加密,外賣網站用同樣的密鑰進行解密。這樣就算中間的黑客截獲了你的請求,但是它沒有密鑰,還是破解不了。

這看起來很完美,但是中間有個問題,你們兩個怎麼來約定這個密鑰呢?如果這個密鑰在互聯網上傳輸,也是很有可能讓黑客截獲的。黑客一旦截獲這個祕鑰,它可以佯作不知,靜靜地等着你們兩個交互。這時候你們之間互通的任何消息,它都能截獲並且查看,就等你把銀行卡賬號和密碼發出來。

我們在諜戰劇裏面經常看到這樣的場景,就是特工破譯的密碼會有個密碼本,截獲無線電臺,通過密碼本就能將原文破解出來。怎麼把密碼本給對方呢?只能通過線下傳輸。

比如,你和外賣網站偷偷約定時間地點,它給你一個紙條,上面寫着你們兩個的密鑰,然後說以後就用這個密鑰在互聯網上定外賣了。當然你們接頭的時候,也會先約定一個口號,什麼“天王蓋地虎”之類的,口號對上了,才能把紙條給它。但是,“天王蓋地虎”同樣也是對稱加密密鑰,同樣存在如何把“天王蓋地虎”約定成口號的問題。而且在諜戰劇中一對一接頭可能還可以,在互聯網應用中,客戶太多,這樣是不行的。

非對稱加密

所以,只要是對稱加密,就會永遠在這個死循環裏出不來,這個時候,就需要非對稱加密介入進來。

非對稱加密的私鑰放在外賣網站這裏,不會在互聯網上傳輸,這樣就能保證這個祕鑰的私密性。但是,對應私鑰的公鑰,是可以在互聯網上隨意傳播的,只要外賣網站把這個公鑰給你,你們就可以愉快地互通了。

比如說你用公鑰加密,說“我要定外賣”,黑客在中間就算截獲了這個報文,因爲它沒有私鑰也是解不開的,所以這個報文可以順利到達外賣網站,外賣網站用私鑰把這個報文解出來,然後回覆,“那給我銀行卡和支付密碼吧”。

先別太樂觀,這裏還是有問題的。回覆的這句話,是外賣網站拿私鑰加密的,互聯網上人人都可以把它打開,當然包括黑客。那外賣網站可以拿公鑰加密嗎?當然不能,因爲它自己的私鑰只有它自己知道,誰也解不開。

另外,這個過程還有一個問題,黑客也可以模擬發送“我要定外賣”這個過程的,因爲它也有外賣網站的公鑰。

爲了解決這個問題,看來一對公鑰私鑰是不夠的,客戶端也需要有自己的公鑰和私鑰,並且客戶端要把自己的公鑰,給外賣網站。

這樣,客戶端給外賣網站發送的時候,用外賣網站的公鑰加密。而外賣網站給客戶端發送消息的時候,使用客戶端的公鑰。這樣就算有黑客企圖模擬客戶端獲取一些信息,或者半路截獲回覆信息,但是由於它沒有私鑰,這些信息它還是打不開。

數字證書

不對稱加密也會有同樣的問題,如何將不對稱加密的公鑰給對方呢?一種是放在一個公網的地址上,讓對方下載;另一種就是在建立連接的時候,傳給對方。

這兩種方法有相同的問題,那就是,作爲一個普通網民,你怎麼鑑別別人給你的公鑰是對的。會不會有人冒充外賣網站,發給你一個它的公鑰。接下來,你和它所有的互通,看起來都是沒有任何問題的。畢竟每個人都可以創建自己的公鑰和私鑰。

例如,我自己搭建了一個網站cliu8site,可以通過這個命令先創建私鑰。

openssl genrsa -out cliu8siteprivate.key 1024

然後,再根據這個私鑰,創建對應的公鑰。

openssl rsa -in cliu8siteprivate.key -pubout -outcliu8sitepublic.pem

這個時候就需要權威部門的介入了,就像每個人都可以打印自己的簡歷,說自己是誰,但是有公安局蓋章的,就只有戶口本,這個才能證明你是你。這個由權威部門頒發的稱爲證書(Certificate)。

證書裏面有什麼呢?當然應該有公鑰,這是最重要的;還有證書的所有者,就像戶口本上有你的姓名和身份證號,說明這個戶口本是你的;另外還有證書的發佈機構和證書的有效期,這個有點像身份證上的機構是哪個區公安局,有效期到多少年。

這個證書是怎麼生成的呢?會不會有人假冒權威機構頒發證書呢?就像有假身份證、假戶口本一樣。生成證書需要發起一個證書請求,然後將這個請求發給一個權威機構去認證,這個權威機構我們稱爲CA( Certificate Authority)。

證書請求可以通過這個命令生成。

openssl req -key cliu8siteprivate.key -new -out cliu8sitecertificate.req

將這個請求發給權威機構,權威機構會給這個證書卡一個章,我們稱爲簽名算法。問題又來了,那怎麼簽名才能保證是真的權威機構簽名的呢?當然只有用只掌握在權威機構手裏的東西簽名了才行,這就是CA的私鑰。

簽名算法大概是這樣工作的:一般是對信息做一個Hash計算,得到一個Hash值,這個過程是不可逆的,也就是說無法通過Hash值得出原來的信息內容。在把信息發送出去時,把這個Hash值加密後,作爲一個簽名和信息一起發出去。

權威機構給證書籤名的命令是這樣的。

openssl x509 -req -in cliu8sitecertificate.req -CA cacertificate.pem -CAkey caprivate.key -out cliu8sitecertificate.pem

這個命令會返回Signature ok,而cliu8sitecertificate.pem就是簽過名的證書。CA用自己的私鑰給外賣網站的公鑰簽名,就相當於給外賣網站背書,形成了外賣網站的證書。

我們來查看這個證書的內容。

openssl x509 -in cliu8sitecertificate.pem -noout -text 

這裏面有個Issuer,也即證書是誰頒發的;Subject,就是證書頒發給誰;Validity是證書期限;Public-key是公鑰內容;Signature Algorithm是簽名算法。

這下好了,你不會從外賣網站上得到一個公鑰,而是會得到一個證書,這個證書有個發佈機構CA,你只要得到這個發佈機構CA的公鑰,去解密外賣網站證書的簽名,如果解密成功了,Hash也對的上,就說明這個外賣網站的公鑰沒有啥問題。

你有沒有發現,又有新問題了。要想驗證證書,需要CA的公鑰,問題是,你怎麼確定CA的公鑰就是對的呢?

所以,CA的公鑰也需要更牛的CA給它簽名,然後形成CA的證書。要想知道某個CA的證書是否可靠,要看CA的上級證書的公鑰,能不能解開這個CA的簽名。就像你不相信區公安局,可以打電話問市公安局,讓市公安局確認區公安局的合法性。這樣層層上去,直到全球皆知的幾個著名大CA,稱爲root CA,做最後的背書。通過這種層層授信背書的方式,從而保證了非對稱加密模式的正常運轉。

除此之外,還有一種證書,稱爲Self-Signed Certificate,就是自己給自己簽名。這個給人一種“我就是我,你愛信不信”的感覺。這裏我就不多說了。

HTTPS的工作模式

我們可以知道,非對稱加密在性能上不如對稱加密,那是否能將兩者結合起來呢?例如,公鑰私鑰主要用於傳輸對稱加密的祕鑰,而真正的雙方大數據量的通信都是通過對稱加密進行的。

當然是可以的。這就是HTTPS協議的總體思路。

當你登錄一個外賣網站的時候,由於是HTTPS,客戶端會發送Client Hello消息到服務器,以明文傳輸TLS版本信息、加密套件候選列表、壓縮算法候選列表等信息。另外,還會有一個隨機數,在協商對稱密鑰的時候使用。

這就類似在說:“您好,我想定外賣,但你要保密我吃的是什麼。這是我的加密套路,再給你個隨機數,你留着。”

然後,外賣網站返回Server Hello消息, 告訴客戶端,服務器選擇使用的協議版本、加密套件、壓縮算法等,還有一個隨機數,用於後續的密鑰協商。

這就類似在說:“您好,保密沒問題,你的加密套路還挺多,咱們就按套路2來吧,我這裏也有個隨機數,你也留着。”

然後,外賣網站會給你一個服務器端的證書,然後說:“Server Hello Done,我這裏就這些信息了。”

你當然不相信這個證書,於是你從自己信任的CA倉庫中,拿CA的證書裏面的公鑰去解密外賣網站的證書。如果能夠成功,則說明外賣網站是可信的。這個過程中,你可能會不斷往上追溯CA、CA的CA、CA的CA的CA,反正直到一個授信的CA,就可以了。

證書驗證完畢之後,覺得這個外賣網站可信,於是客戶端計算產生隨機數字Pre-master,發送Client Key Exchange,用證書中的公鑰加密,再發送給服務器,服務器可以通過私鑰解密出來。

到目前爲止,無論是客戶端還是服務器,都有了三個隨機數,分別是:自己的、對端的,以及剛生成的Pre-Master隨機數。通過這三個隨機數,可以在客戶端和服務器產生相同的對稱密鑰。

有了對稱密鑰,客戶端就可以說:“Change Cipher Spec,咱們以後都採用協商的通信密鑰和加密算法進行加密通信了。”

然後發送一個Encrypted Handshake Message,將已經商定好的參數等,採用協商密鑰進行加密,發送給服務器用於數據與握手驗證。

同樣,服務器也可以發送Change Cipher Spec,說:“沒問題,咱們以後都採用協商的通信密鑰和加密算法進行加密通信了”,並且也發送Encrypted Handshake Message的消息試試。當雙方握手結束之後,就可以通過對稱密鑰進行加密傳輸了。

這個過程除了加密解密之外,其他的過程和HTTP是一樣的,過程也非常複雜。

上面的過程只包含了HTTPS的單向認證,也即客戶端驗證服務端的證書,是大部分的場景,也可以在更加嚴格安全要求的情況下,啓用雙向認證,雙方互相驗證證書。

重放與篡改

其實,這裏還有一些沒有解決的問題,例如重放和篡改的問題。

沒錯,有了加密和解密,黑客截獲了包也打不開了,但是它可以發送N次。這個往往通過Timestamp和Nonce隨機數聯合起來,然後做一個不可逆的簽名來保證。

Nonce隨機數保證唯一,或者Timestamp和Nonce合起來保證唯一,同樣的,請求只接受一次,於是服務器多次受到相同的Timestamp和Nonce,則視爲無效即可。

如果有人想篡改Timestamp和Nonce,還有簽名保證不可篡改性,如果改了用簽名算法解出來,就對不上了,可以丟棄了。

小結

好了,這一節就到這裏了,我們來總結一下。

加密分對稱加密和非對稱加密。對稱加密效率高,但是解決不了密鑰傳輸問題;非對稱加密可以解決這個問題,但是效率不高。

非對稱加密需要通過證書和權威機構來驗證公鑰的合法性。

HTTPS是綜合了對稱加密和非對稱加密算法的HTTP協議。既保證傳輸安全,也保證傳輸效率。

本文出自劉超的《趣談網絡協議》專欄,超過2.5w名程序員都在學習的專欄,極客時間最受歡迎課程之一,像小說一樣的網絡協議入門課。

訂閱福利:限時拼圖僅需¥79,原價¥99。點擊訂閱

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章