HTTPS 與安全感
大家好,我是丹先生。每次超人脫下衣服露出胸膛,那個大大的 S,人們就會有一種奇怪的安全感。每次打開網頁,看到網址旁邊的小鎖,大多數人也會覺得網絡很安全。因為網站使用了 HTTPS,這裡的 S 代表安全,雖然和超人胸前的 S 含義不同,但都能讓人感到安全。然而仔細想想,小鎖和超人的 S 都只是標誌,並不一定絕對安全。HTTPS 也有弱點,就像超人遇到氪星石一樣。
信息安全的核心問題
要了解信息安全的弱點,必須圍繞三個核心問題。假設金角大王和銀角大王不在同一個山洞,需要通過飛歌傳輸的方式聯繫。為了防止別人知道通話內容,他們準備了信件、盒子和鎖,且只有他們倆有相同的盒子鑰匙。
對稱加密
這種加密方法叫做對稱加密,因為只有他們擁有兩把鑰匙,這兩把鑰匙都是私鑰。但問題來了,兩個人必須見面才能確定這把鑰匙。如果只有一個人有兩把私鑰,把另一把私鑰發給對方,很可能會被攔截。要是兩個人見不了面,怎麼把「毒藥」安全地送給對方呢?
秘密鑰匙交換
此時金角大王把兩對磁化「毒藥」放進盒子並鎖上,這個小鎖只能用金角大王的金鑰匙打開,然後送給銀角大王。銀角大王收到後,也鎖上盒子,這個小鎖只能用銀角大王的銀鑰匙打開,再送給金角大王。金角大王收到後,用金鑰匙打開金鎖,把剩下鎖著的盒子送給銀角大王。銀角大王收到後,直接用銀鑰匙打開盒子,得到金角大王的兩對對稱加密私鑰中的一把。因為金鑰匙和銀鑰匙都是他們自己的,這樣就能成功地把相應的加密私鑰分享給對方,這就是秘密鑰匙交換。
對稱加密通信
用秘密鑰匙交換方法,是否能繼續正常通信呢?也就是直接把信放進去,重複剛才的解鎖和鎖定過程。答案是可以的,但每次這樣來回很費時費力。如果電腦用這種方式傳輸文件,每個主機隨時都會發出這樣的聲音。所以這種方法常用於加密和協商對稱性,畢竟一般秘密鑰匙的大小相對於文件來說比較小。雙方協商好私鑰的對稱性後,就會有一種對稱加密形式用於正常的加密通信。
通信對象確認問題
但這裡還有個問題,如果有人攔截了中間鎖著的盒子,完全有可能更換盒鎖,然後更改裡面信件的內容,這樣就無法確定是誰在和誰通信。
非對稱加密
為了解決這個問題,金角大王製作了兩把相應的鑰匙:公鑰和私鑰。公鑰是公開的,私鑰不能被打開。最神奇的是,只有公鑰能打開私鑰鎖上的東西,相當於私鑰加密,公鑰解密。
公鑰與私鑰的使用
金角大王製作了很多公鑰並發送出去,讓銀角大王得到這個公鑰。金角大王處理信件的特殊內容,提取裡面所有重複的字並用數字標記,得到一條特殊的線,這條特殊的線對應著信件內容。如果信件內容改變,這條特殊的線也會改變。金角大王把這條特殊的「制服」放在另一個盒子裡,用私鑰鎖上,然後把特殊的「制服」和信件直接送給銀角大王。不考慮信件被加密的情況,銀角大王收到信件後,用和金角大王一樣的方法得到一條特殊的「制服」,並用公鑰打開盒子得到金角大王的特殊「制服」。比較兩條特殊的「制服」,就知道是金角大王發來的信件,因為只有這個公鑰能打開相應私鑰加密的鎖,而且兩個人使用相同的計算特殊「制服」的方法,這樣就能驗證信件內容是否被修改。實際上,這種計算特殊「制服」的方法相當於哈希計算,特殊的「制服」就是哈希值。
非對稱加密原理
這裡正確的私鑰和公鑰加密方法是一種非對稱加密方法,證明也是這樣的原理。首先交換秘密鑰匙,然後使用對稱加密方法進行加密通信,中間使用哈希方法配合,這實際上是 HTTPS 運作的核心原理。
TLS 協議
HTTPS 中的 S 實際上有一個單獨的協議來運作,那就是今天的主角 TLS。雖然 TLS 的前身是 SSL,很多人仍然把 SSL 叫做 TLS,但現在 TLS 和 SSL 有很大不同,尤其是從 TLS 1.2 演變到 TLS 1.3 版本。
TLS 1.2 的核心算法
TLS 1.2 有兩個核心算法:RSA 和 DH 算法。
-
RSA 算法:如果使用 RSA 交換鑰匙,服務器有正確的公鑰和私鑰。公鑰加密後,只有私鑰能解鎖,加密後連公鑰都無法解鎖。客戶端收到服務器發送的公鑰後,可以用公鑰加密並發出用於協商的秘密鑰匙,服務器有對應的私鑰,所以能用私鑰得到密碼,這樣雙方就交換了未知的密碼。
-
DH 算法:如果使用 DH 交換密碼,情況就不同了。雙方都有私鑰,並且必須向對方提供自己的協商參數。收到對方的協商參數後,雙方用自己的私鑰和對方的參數計算出相同的秘密鑰匙,這和之前金角大王交換秘密鑰匙的方式一樣。
TLS 1.3 的改變
由於 DH 算法雙方必須生成自己的私鑰和參數,所以每次都能生成不同的隨機數。即使將來真的被人破解,也只是一個隨機的隨機數。而 RSA 算法不同,使用 RSA 不需要雙方每次都生成私鑰和參數,只需要一方有私鑰和公鑰,然後把公鑰發給對方。一種相對簡單的實現方法是讓這個公鑰私鑰變成靜態的,在一段時間內不變,發送者和接收者都很方便。但問題是,如果私鑰暴露,之前通信的內容又被攔截並存儲,那麼所有之前的內容都會被解碼。根據密碼學,這種靜態的 RSA 算法有一個前提問題。實際上,不使用臨時隨機數的 DH 算法也有問題。因此,這種靜態的 RSA 和 DH 秘密交換算法在 TLS 1.3 中被移除。
非靜態 DH 算法的安全性
此時可能有同學問,現在雙方使用非靜態 DH 算法安全嗎?首先,靜態和非靜態相當於不更改密碼和經常更改密碼。如果選擇非靜態,第二件要考慮的是 DH 算法中的參數,這是否相當於設置一個容易破解的密碼或設置一個不那麼容易破解的密碼?
DH 算法的難度
DH 算法難以理解的解決方案是減法問題。例如,5 的平方除以 23 等於 4,用計算器可以很快算出。但如果知道所有的數字,不知道這個 4,就很難反推。如果 4、5、23 都是非常大的數字,雖然知道,但反推會更困難。因此,DH 算法中使用的參數越大,被反推的難度就越大。
兼容性與參數問題
但由於有些主機設備不支持新版本的 TLS,或者只支持 SSL,而 TLS 1.2 協議支持版本下載,所以客戶端和服務端可以升級通信。此外,DH 算法的參數由服務器決定,如果服務器配置不正確或沒有及時升級,可能會有問題。這裡的參數就是 DH 算法中的 P 和 G,由服務器選擇,可以有很多組合。雖然 DH 算法使用了減法問題,但並不意味著使用 DH 算法就安全,因為不是所有的 P、E、G 組合都是安全的。
密碼套件
TLS 1.2 的密碼套件
在進行 TLS 1.2 握手的前兩步,客戶端和服務端會協商加密的細節,其中包括使用什麼算法的協商,這一串「制服」就是密碼套件了。這裡分別代表協議名稱、交換的密碼、驗證、對稱加密和模式以及哈希。這些不同的功能對應著很多不同的算法來實現,因此這個密碼套件可以有很多不同的組合,TLS 1.2 定義了總共 37 種不同的組合。
TLS 1.3 的密碼套件
TLS 1.3 將協議名稱、對稱加密和哈希的組合變成了五種類型的密碼套件,看起來更酷,但似乎有點不對。難道不需要秘密交換和驗證這麼重要的算法嗎?其實不是不需要,而是 TLS 1.3 只支持三種鑰匙交換模式。
鑰匙交換模式
-
PSK-only 模式:基本上可以說是一種對稱加密方法,讓客戶端和服務端使用推薦的固定鑰匙。
-
其他兩種模式:都有 DH 算法,這意味著雙方都需要生成試驗和協商參數。而且正如之前所說,TLS 1.3 中可選擇的參數少了很多,客戶端可以在一開始就發送 DH 算法中的協商參數,而不需要等到所有的算法和參數都發送出去,這樣性能得到了提高。
加密模式
組密碼
用於加密的密碼是其中一種,叫做組密碼,DS 和 AES 算法都會用到。組密碼的原理是這樣的,例如有 10 個字符,如果密碼正好是 10 個字符,就可以直接用這個密碼加密。但如果密碼只有 4 個字符,就只能把這十個字符分成三部分,用四個字符的密碼分別加密每一部分。但第三部分只有兩個字符,密碼有四個字符無法加密,因此在加密前需要填充內容。例如,只剩一個空格就填 1,只剩兩個空格就填 2,只剩三個空格就填 3,以此類推。
CBC 模式
為了讓密碼更難猜測,計算機中有一種叫做隨機計算的方法。對於二階,0 和 0 或 1 和 1 計算得到 0,如果 1 和 0 或 0 和 1 計算得到 1。對於剛才的內容,可以取一個和密碼長度相同的隨機數,讓隨機數和密碼塊進行隨機計算,然後進行加密,得到密碼和第二個名稱塊進行隨機計算,然後加密,以此類推。這就是 CBC 模式,使用相同的密碼,但可以得到更不同的密碼。一般來說,就是先解密再加密。當服務器收到密碼時,操作正好相反,即先解密再解密。
TLS 1.3 對加密模式的改變
由於黑客可以通過修改密碼檢查服務器的響應來嘗試移除密碼,所以 CBC 模式密碼在 TLS 1.3 中不再使用。除了組密碼,還有一種序列密碼 RC4,RC4 的 R 是 RSA 中的 R,代表同一個人,RC4 也有漏洞,已經被移除。對於對稱加密,TLS 1.3 使用 AEAD 加密方法,AEAD 有不同的形式,原理可以簡單地這樣理解:首先加密一串數字得到哈希值,然後生成隨機數並讓隨機數加 1,接下來進行加密,加密後進行轉移操作得到第一個密碼,加密後進行轉移操作得到新的哈希值,接下來進行加密,加密後進行轉移操作得到第二個密碼,第二個密碼和前一個哈希值得到新的哈希值,以此類推。對於服務器,收到密碼後,是先驗證再解密,而不是先解密再驗證。如果驗證有問題,就不需要解密,所以黑客很難猜測。
簽名的填充問題
TLS 1.2 中的填充問題
如果在 TLS 1.2 中選擇 RSA 交換鑰匙,客戶端收到服務器發送的證書後,會從證書中獲得相應的鑰匙。此時,客戶端會生成預設鑰匙,這個預設鑰匙用於生成繪圖鑰匙。因此,會用真實的公鑰加密史前秘密鑰匙,然後發送出去。因為服務器有私鑰,所以可以解密並獲得史前秘密鑰匙,這樣雙方都可以生成解密的秘密鑰匙。但問題是,如果這裡添加史前秘密鑰匙,只有 48 個解密,即 384 位。如果服務器的 RSA 公鑰長度是 2048 位,由於長度問題,必須填充到預設密碼,大概是這樣的形式:用右字填充,用右字填充,用右字填充……黑客仍然可以使用服務器的響應來判斷。這裡說的實際上是 PKCS1 1.5 版本的填充循環。
TLS 1.3 中的改變
在 TLS 1.3 中,它被更改為用 PSS 填充,簡單地說,就是使用更複雜的操作來加密。
TLS 握手
TLS 1.2 握手
簡單回顧一下 TLS 1.2 的握手過程。首先,客戶端會說你好,生成客戶端隨機數,並發送聲明支持的密碼套件。服務器收到後,選擇密碼套件。假設選擇使用 DH 作為密碼交換算法,它會生成客戶端隨機數,生成 DH 協商參數,然後用證書給客戶端一個隨機數、服務器隨機數和 DH 參數加密。加密後的數據是數字簽名,最後和證書一起發送出去。此時,客戶端會用證書解密數字簽名進行比較,如果準備成功,就會驗證服務器的身份,然後發送自己的 DH 協商參數,這樣雙方就可以使用 DH 協商參數生成預設鑰匙,然後雙方使用預設鑰匙和一開始的隨機數生成繪圖鑰匙,然後加密正式內容。
TLS 1.3 握手
對於 TLS 1.3,可以說只能使用 DH 算法交換鑰匙,並且可選的參數組。因此,除了客戶端一開始生成隨機數外,可以直接生成 DH 協商參數。畢竟被猜對的概率會很低。服務器收到後,也生成隨機數和 DH 協商參數並發送出去。接下來是加密內容,因為服務器已經有了生成密碼的所有參數,所以在發送證書時可以加密。客戶端收到服務器的隨機數和 DH 協商參數後,也能夠生成密碼,並且可以驗證服務器的證書和簽名。後面也是加密正式內容。雖然還有很多細節沒有談到,但核心原理現在已經知道了。這就是本視頻的內容,下次見。