真正“搞”懂HTTPS協議16之安全的實現

Zaking發表於2023-02-14

  上一篇噢,我們搞明白了什麼是安全的通訊,這個很重要,特別重要,敲黑板!!

  然後,我們還學了HTTPS到底是什麼,以及HTTPS真正的核心SSL/TLS是什麼。最後我們還聊了聊TLS的實現,也就是OpenSSL。

  那麼這一篇,就會稍微長一點了,很重要!我們來聊一聊,安全的四大特性是如何被TLS實現的。

一、機密性的實現

  說起機密性,不知道大家第一時間是不是跟我想的一樣。加密唄。一點毛病沒有~就是加密。加密說白了就是把誰都能看的懂的內容,轉換成只有擁有鑰匙的人才看的懂的內容。這裡的“鑰匙”就叫做“金鑰”(key),加密前的訊息叫“明文”(plain text/clear text),加密後的亂碼叫“密文”(cipher text),使用金鑰還原明文的過程叫“解密”(decrypt),是加密的反操作,加密解密的操作過程就是“加密演算法”。

  所有的加密演算法都是公開的,任何人都可以去分析研究,而演算法使用的“金鑰”則必須保密。

  那麼,這個關鍵的“金鑰”又是什麼呢?

  由於 HTTPS、TLS 都執行在計算機上,所以“金鑰”就是一長串的數字,但約定俗成的度量單位是“位”(bit),而不是“位元組”(byte)。比如,說金鑰長度是 128,就是 16 位元組的二進位制串,金鑰長度 1024,就是 128 位元組的二進位制串。

  按照金鑰的使用方式,加密可以分為兩大類:對稱加密非對稱加密

一)對稱加密

  對稱加密很好理解,就是指加密和解密都是使用的同一個金鑰,是”對稱“的。只要保證了金鑰的安全,那整個通訊過程就可以說具備了機密性。

  舉個例子,你想要登入某個網站,只要事先與它約定好使用一個對稱金鑰,通訊過程中全是用金鑰加密後的密文,只有你和網站才能解密,駭客即使能夠竊聽,看到的也是亂碼,因為沒有金鑰無法解出明文,所以就實現了機密性。

  真正“搞”懂HTTPS協議16之安全的實現

   這圖片我複製過來的~懶得畫了,哈哈哈。

  TLS 裡有非常多的對稱加密演算法可供選擇,比如 RC4、DES、3DES、AES、ChaCha20 等,但前三種演算法都被認為是不安全的,通常都禁止使用,目前常用的只有 AES 和 ChaCha20

  AES 的意思是“高階加密標準”(Advanced Encryption Standard),金鑰長度可以是 128、192 或 256。它是 DES 演算法的替代者,安全強度很高,效能也很好,而且有的硬體還會做特殊最佳化,所以非常流行,是應用最廣泛的對稱加密演算法。

  ChaCha20 是 Google 設計的另一種加密演算法,金鑰長度固定為 256 位,純軟體執行效能要超過 AES,曾經在移動客戶端上比較流行,但 ARMv8 之後也加入了 AES 硬體最佳化,所以現在不再具有明顯的優勢,但仍然算得上是一個不錯的演算法。

  所以,總結下來,我們只要知道TLS最常用的對稱加密演算法就是AES,其它的加密演算法要麼不安全,要麼就跟AES差不多。

加密分組模式

  對稱加密還有個”分組模式“的概念,它可以讓演算法用固定長度的金鑰加密任意長度的明文。

  最早有 ECB、CBC、CFB、OFB 等幾種分組模式,但都陸續被發現有安全漏洞,所以現在基本都不怎麼用了。最新的分組模式被稱為 AEAD(Authenticated Encryption with Associated Data),在加密的同時增加了認證的功能,常用的是 GCM、CCM 和 Poly1305

  把上面這些組合起來,就可以得到 TLS 密碼套件中定義的對稱加密演算法。

  比如,AES128-GCM,意思是金鑰長度為 128 位的 AES 演算法,使用的分組模式是 GCM;ChaCha20-Poly1305 的意思是 ChaCha20 演算法,使用的分組模式是 Poly1305。

二)非對稱加密

  對稱加密看上去好像還不錯,但是其中有一個很大的問題,就是通訊的雙方如何安全的把金鑰傳遞給對方,術語叫做”金鑰交換“。

  因為再對稱加密演算法中,金鑰成了密文的關鍵,只要持有金鑰,就能解密密文獲得明文資料。雖然駭客無法直接解密傳輸過程中的密文,但是可以攔截捕獲傳輸過程中傳遞的金鑰,那他就可以在之後隨意解密收發的資料,通訊過程也就沒有機密性可言了。

  怎麼解決這個問題呢,嗯……那就再把金鑰也加密一下,但是傳輸加”密金鑰的金鑰“又出現了同樣的問題,得~~這樣不就死迴圈了?所以,只用對稱加密演算法,是絕對無法解決金鑰交換的問題的。

  所以,就出現了非對稱加密(也叫公鑰加密演算法)。

  它有兩個金鑰,一個叫“公鑰”(public key),一個叫“私鑰”(private key)。兩個金鑰是不同的,“不對稱”,公鑰可以公開給任何人使用,而私鑰必須嚴格保密。

  公鑰和私鑰有個特別的“單向”性,雖然都可以用來加密解密,但公鑰加密後只能用私鑰解密,反過來,私鑰加密後也只能用公鑰解密。這個邏輯很重要,我們後面還會接觸到。要記住噢~

  非對稱加密可以解決“金鑰交換”的問題。網站秘密保管私鑰,在網上任意分發公鑰,你想要登入網站只要用公鑰加密就行了,密文只能由私鑰持有者才能解密。而駭客因為沒有私鑰,所以就無法破解密文。

真正“搞”懂HTTPS協議16之安全的實現

  非對稱加密演算法的設計要比對稱演算法難得多,在 TLS 裡只有很少的幾種,比如 DH、DSA、RSA、ECC 等。

  RSA 可能是其中最著名的一個,幾乎可以說是非對稱加密的代名詞,它的安全性基於“整數分解”的數學難題,使用兩個超大素數的乘積作為生成金鑰的材料,想要從公鑰推算出私鑰是非常困難的。

  10 年前 RSA 金鑰的推薦長度是 1024,但隨著計算機運算能力的提高,現在 1024 已經不安全,普遍認為至少要 2048 位。

  ECC(Elliptic Curve Cryptography)是非對稱加密裡的“後起之秀”,它基於“橢圓曲線離散對數”的數學難題,使用特定的曲線方程和基點生成公鑰和私鑰,子演算法 ECDHE 用於金鑰交換,ECDSA 用於數字簽名。

  比起 RSA,ECC 在安全強度和效能上都有明顯的優勢。160 位的 ECC 相當於 1024 位的 RSA,而 224 位的 ECC 則相當於 2048 位的 RSA。因為金鑰短,所以相應的計算量、消耗的記憶體和頻寬也就少,加密解密的效能就上去了,對於現在的移動網際網路非常有吸引力。

  我們要記住RSA、ECC這兩個非對稱加密演算法。很重要。

三)混合加密

  那~我們直接用非對稱加密不就完美了麼?也不行,雖然非對稱加密沒有”金鑰交換“的問題,但因為它們都是基於複雜的數學難題,運算速度很慢,即使是 ECC 也要比 AES 差上好幾個數量級。如果僅用非對稱加密,雖然保證了安全,但通訊速度有如烏龜、蝸牛,實用性就變成了零。

  那怎麼辦呢?開動腦筋想一想?

  我們可以把對稱加密和非對稱加密結合起來,兩者互相取長補短,即能高效地加密解密,又能安全地金鑰交換。

  這就是現在 TLS 裡使用的混合加密方式

  在通訊剛開始的時候使用非對稱演算法,比如 RSA、ECDHE,首先解決金鑰交換的問題。

  然後用隨機數產生對稱演算法使用的“會話金鑰”(session key),再用公鑰加密。因為會話金鑰很短,通常只有 16 位元組或 32 位元組,所以慢一點也無所謂。對方拿到密文後用私鑰解密,取出會話金鑰。這樣,雙方就實現了對稱金鑰的安全交換,後續就不再使用非對稱加密,全都使用對稱加密。

真正“搞”懂HTTPS協議16之安全的實現

  這樣混合加密就解決了對稱加密演算法的金鑰交換問題,而且安全和效能兼顧,完美地實現了機密性。

  到目前為止還沒完,我們還需要解決其它三個特性的問題才可以。萬里長征的第一步要走穩。

二、實現完整性

  上一小節,我們透過學習對稱加密和非對稱加密的混合加密方式,瞭解了TLS是如何實現通訊的機密性的,但是隻有機密性還遠遠不夠。

  雖然駭客拿不到會話金鑰,無法破解密文,但是可以透過竊聽足夠多的密文,再嘗試修改、重組後發給網站。因為沒有完整性保證,伺服器只能“照單全收”,然後他就可以透過伺服器的響應獲取進一步的線索,最終就會破解出明文。

  另外,駭客也可以偽造身份釋出公鑰。如果你拿到了假的公鑰,混合加密就完全失效了。你以為自己是在和“某寶”通訊,實際上網線的另一端卻是駭客,銀行卡號、密碼等敏感資訊就在“安全”的通訊過程中被竊取了。

  那麼我們接下來要學習的就是,如何保證會話的完整性,讓駭客修改後的報文被伺服器拒絕。

一)摘要演算法

  實現完整性的手段主要是摘要演算法(Digest Algorithm),也就是常說的雜湊函式、雜湊函式(Hash Function)。

  你可以把摘要演算法理解成一種單向的壓縮演算法,它能夠把任意長度的資料壓縮成固定長度、且獨一無二的”摘要“字串,就好像是給資料加上了一個”指紋“。摘要演算法只有演算法,沒有金鑰,也無法解密,所以也無法逆推出原文。

  摘要演算法實際上是把資料從一個大空間,對映到了一個小空間,所以就存在衝突(也叫做碰撞)的可能性,就如同現實中的指紋一樣,可能會有兩份不同的原文對應相同的摘要。好的摘要演算法必須能夠“抵抗衝突”,讓這種可能性儘量地小。

  你一定在日常工作中聽過、或者用過 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它們就是最常用的兩個摘要演算法,能夠生成 16 位元組和 20 位元組長度的數字摘要。但這兩個演算法的安全強度比較低,不夠安全,在 TLS 裡已經被禁止使用了。目前 TLS 推薦使用的是 SHA-1 的後繼者:SHA-2。

  SHA-2 實際上是一系列摘要演算法的統稱,總共有 6 種,常用的有 SHA224、SHA256、SHA384,分別能夠生成 28 位元組、32 位元組、48 位元組的摘要。

二)完整性的實現

  摘要演算法保證了”數字摘要“和原文是等價的。所以,我們只需要在原文後附上它的摘要,就能夠保證資料的完整性。

  伺服器透過計算源資料的摘要,然後和傳過來的摘要比對一下,就可以知道是否是完整的未被修改的資料。如果駭客在中間哪怕改動了一個標點符號,摘要也會完全不同,網站計算比對就會發現訊息被竄改,是不可信的。

  不過摘要演算法沒有機密性,如果明文傳輸,那麼駭客可以修改訊息後把摘要也一起改了,網站還是鑑別不出完整性。

  所以,真正的完整性必須要建立在機密性之上,在混合加密系統裡用會話金鑰加密訊息和摘要,這樣駭客無法得知明文,也就沒有辦法動手腳了。這有個術語,叫雜湊訊息認證碼(HMAC)。

三、身份認證與不可否認

  加密演算法結合摘要演算法,可以說資料在通訊”過程“中是比較安全的了。但是隻是過程中的安全,還不行,我們還要關注通訊的兩個端點。

  駭客可以偽裝成網站來竊取資訊。但是反過來,駭客還可以偽裝成”你“,向網站傳送支付、轉賬資訊,網站沒有辦法確認你是誰,錢就這麼被偷走了。

  那,在現實生活中,我們通常透過簽名、蓋章、加身份證號,來在合同上確認你是誰,確認這份檔案確實是你簽署的,可以負法律責任了。

  那,我們回憶一下,我再限定一下、縮小一下範圍,我們在第一小節學習的內容中,有啥是可以確認你是誰的呢?

  沒錯,這個東西就是非對稱加密裡的“私鑰”,使用私鑰再加上摘要演算法,就能夠實現“數字簽名”,同時實現“身份認證”和“不可否認”。

  數字簽名的原理其實很簡單,就是把公鑰私鑰的用法反過來,之前是公鑰加密、私鑰解密,現在是私鑰加密、公鑰解密。

  但是又因為非對稱加密效率太低,所以私鑰只加密原文的摘要,這樣運算量就小的多,而且得到的數字簽名也很小,方便保管和傳輸。

  簽名和公鑰一樣完全公開,任何人都可以獲取。但這個簽名只有用私鑰對應的公鑰才能解開,拿到摘要後,再比對原文驗證完整性,就可以像簽署檔案一樣證明訊息確實是你發的。

真正“搞”懂HTTPS協議16之安全的實現

  剛才的這兩個行為也有專用術語,叫做“簽名”和“驗籤”。

  只要你和網站互相交換公鑰,就可以用“簽名”和“驗籤”來確認訊息的真實性,因為私鑰保密,駭客不能偽造簽名,就能夠保證通訊雙方的身份。

  到現在哈,其實我們就解決了所有的問題。機密性透過對稱加密和非對稱加密的混合加密來解決,完整性就是數字摘要,身份認證和不可否認則是透過數字簽名(其實就是”反過來了“,能理解不?)來解決。

  但是~還沒完~

四、信任危機

  現在看起來很美好了,但是還有個問題,就是”我“可以釋出公鑰,那麼這個我就可能不是”我“,而是駭客怎麼辦?駭客可以偽造公鑰,換句話說,就是我怎麼確定你釋出的公鑰是”你“釋出的,或者是伺服器釋出的呢?

  嗯……這樣的問題就叫做”公鑰的信任“問題。

  那,我給這個公鑰再用私鑰加密一下呢?得……那又會陷入無盡的迴圈中,所以,此時就必須引入外力來解決了,找一個公認得可信得第三方,讓它作為”信任的起點,遞迴的終點“,構建起公鑰的信任鏈。

一)數字證書和CA

  我們要引入的這個第三方,就是CA(Certificate Authority,證書認證機構),它就像網路世界裡的公安局、教育部、公證中心,具有極高的可信度,由它來給各個公鑰簽名,用自身的信譽來保證公鑰無法偽造,是可信的。

  CA 對公鑰的簽名認證也是有格式的,不是簡單地把公鑰繫結在持有者身份上就完事了,還要包含序列號、用途、頒發者、有效時間等等,把這些打成一個包再簽名,完整地證明公鑰關聯的各種資訊,形成“數字證書”(Certificate)。

  知名的 CA 全世界就那麼幾家,比如 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它們簽發的證書分 DV、OV、EV 三種,區別在於可信程度。

  DV 是最低的,只是域名級別的可信,背後是誰不知道。EV 是最高的,經過了法律和審計的嚴格核查,可以證明網站擁有者的身份(在瀏覽器位址列會顯示出公司的名字,例如 Apple、GitHub 的網站)。

  那,信任鏈到頭了,就到根了,那根怎麼證明自己呢?

  這還是信任鏈的問題。小一點的 CA 可以讓大 CA 簽名認證,但鏈條的最後,也就是 Root CA,就只能自己證明自己了,這個就叫“自簽名證書”(Self-Signed Certificate)或者“根證書”(Root Certificate)。你必須相信,否則整個證書信任鏈就走不下去了。

  有了這個證書體系,作業系統和瀏覽器都內建了各大 CA 的根證書,上網的時候只要伺服器發過來它的證書,就可以驗證證書裡的簽名,順著證書鏈(Certificate Chain)一層層地驗證,直到找到根證書,就能夠確定證書是可信的,從而裡面的公鑰也是可信的。

二)證書體系的弱點

  聊了這麼多,終於確保了資訊傳輸的安全,但是,也不是完美的。由於根證書是自證明式的,所以如果CA出了問題,被駭客攻陷,或者失誤,或者被欺騙,雖然此時釋出的證書是真的,但是它所代表的網站卻是假的。

  這些情況其實都實際發生過。所以,我們還需要給證書體系打上一些補丁。

  針對證書欺騙問題,開發出了CRL(證書吊銷列表)和OCSP(線上證書狀態協議),及時廢止有問題的證書。

  對於被攻陷的情況,因為涉及的證書太多,,就只能作業系統或者瀏覽器從根上“下狠手”了,撤銷對 CA 的信任,列入“黑名單”,這樣它頒發的所有證書就都會被認為是不安全的。

五、小結

  這篇文章很重要,特別重要。大家一定要好好學習。並且這篇文章內容很多,但是總結起來其實可以概括為兩句話。

  一個是,資訊傳輸的安全需要具備四大特性,機密性、完整性、身份認證和不可否認

  一個是,安全的終點是自證明的第三方

  其它的部分,其實都是TLS針對四大特性的具體實現了。

  本系列就快結束了~~~大概還有兩三篇的內容。堅持~~不一定會勝利,但是不堅持,肯定會失敗。共勉吧~

  哦對,其實這篇文章是抄的~

相關文章