安全的密鑰交換

春麗 S.T.E.M.
11 min readFeb 9, 2024

--

目錄
1. 前情提要
2. RSA、AES
3. Recheck 流程
4. 簽名的作用機制
4-1 最後
4-2 最後的最後

⦿ 前情提要
⦿ RSA、AES
⦿ Recheck 流程
⦿ 簽名的作用機制
⦿ 最後
⦿ 最後的最後

前情提要

前一篇文章中,我們提到了 PKI,提到了信任鏈,以及驗證機制非對稱加密,這邊快速地再回顧一下驗證機制。

同樣使用 Alice 跟 Bob,若是兩個不同用戶要做訊息交換,Alice 跟 Bob 拿到了 AWS 頒發的憑證,其中的簽名是 AWS 以私鑰產生的,憑證裡也包含了各自的公鑰;而雙方除了這個預產生(非由 CSR 獲取)的憑證,AWS 也給了私鑰,私鑰是經由連結下載而得,且只有一次機會,AWS 也不會幫你保留。

在網路通訊中,若你要以 HTTPS 連到某網站,Browser 必須要裝有該網站的憑證,Browser 方可進行 HTTPS 連線,而憑證是幫忙解決身份驗證的部份,而非資料加密的部份。

接著,Alice 跟 Bob 要做溝通,必須經過兩件事,一件是驗證,一件是加密,驗證指的是身份確認,加密指的是明文的檔案變成需要解密的密文

我們仍先將重點放在驗證,因為加密涉及到密鑰的交換,這是本篇的重點。Alice 跟 Bob 在溝通時,Alice 會將簽名傳給 Bob(由 Alice 的私鑰產生),Bob 利用 Alice 的公鑰驗證簽名,即是驗證了 Alice 的身份,更正確地說,是驗證了 Alice 的公鑰。

在這當中,公鑰交換就變成重點了,且一不小心就成為風險,於是我們需要可靠的第三方,在這邊的例子是 AWS,不過更重要的是在 AWS 的世界裡,Alice 跟 Bob 並不直接做溝通,而是透過 IoT Core 做 Gateway。

也就是 Alice => IoT Core => Bob 或 Bob => IoT Core => Alice,不過前次文章在這一段只特別提了驗簽,這邊試著把加密驗簽再順過。

回目錄

繼續閱讀|回目錄

RSA、AES

這邊不會說 RSA、AES 背後的演算法,以及它是如何實現的,我們只要知道 RSA 是用於非對稱加密,AES 是用於對稱加密,這也就是說 RSA 會形成密鑰對,AES 只會形成單一密鑰

而 RSA 加解密過程較慢(花較多時間)但安全(暴力破解也須較多時間),所以不適用在大量 Data 的資料交換,但我們可以使用這個算法來做密鑰交換;AES 的優點是較快(花較少時間),但不夠安全(較容易破解),所以,實際在網路溝通會兩者會搭配一起使用。

從 Alice(Client)、AWS IoT Core(Server)、Bob(Client) 的交流來看,我們先嘗試了解從 Client 到 Server 這段,如下:

首先 AWS 產生了非對稱加密(RSA)的公私鑰,Bob 產生了對稱加密(AES)的密鑰,公私鑰是用來實踐密鑰交換的,而 Bob 的密鑰則是用來將明文變成密文的,AWS 會將 RSA 公鑰傳給 Bob,如同 root CA 中的公鑰,Bob 就可以用這個公鑰來加密密鑰,當然,Bob 也要使用密鑰(AES Key)去加密最後要傳送給 Alice 的 Data。

當 IoT Core 收到這兩個訊息,首先會用 RSA Private Key 解開加密的密鑰(AES Key),拿到 AES Key 後,再用 AES Key 解開 Data。

這樣的好處是,密鑰交換這個行為受到了保護,而傳送的資料也不是明文,是密文,再者,加密的速度也快,涵蓋了 RSA、AES 的優點。

但這缺乏了 AES Key 是否就是 Bob 發出來的驗證,我們先假定這不會有錯。那麼,當 Bob 的資料安全地到了 IoT Core,IoT Core 再將訊息轉發給 Alice。

這張圖相當有問題,因前面說了 RSA 是比較曠日費時的。

如果 AWS 利用 RSA Private Key 去加密 Data,傳給 Alice,而 Alice 已經有 RSA Public Key(同 Bob),就可以解開原先來自 Bob 的 Data 了。

以單向傳遞來說這種形式並沒錯,不過 MQTT 並不是在有資料傳送時才建立的連接,因為 MQTT 是一種長連接,而不是像 HTTPS 的單次連接(RESTful),當然,在 HTTP 的單次連接也可以轉成 Web Socket 協議建立長連接,不過我們還是先專注在 MQTT 上。

我們再檢視一次 Bob 到 AWS 這一部份,如果中途遭到攔截,由於攔截者沒有 AWS 的 private key,所以它也沒辦法得到 Bob 的密鑰。

但 AWS 到 Alice 這一段,如果中途遭到攔截,由於攔截者是可能有 AWS 的 Public Key 的,那這段訊息便會被竊取了,所以,實際上應該是 AWS 用 Alice 的公鑰加密那段訊息,Alice 收到後,用自己的私鑰解密,得到原先 Bob 欲傳送的訊息;如果中途被攔截了,竊取者沒有 Alice 的 private key,所以仍然沒辦法知道 Bob 傳送的訊息是什麼。

所以,第二張圖修正如下:

差別僅在於 RSA Public Key 是 Alice 的,AES Key 是 IoT Core 的;當 Alice 收到資料後,解開得到 AES Key,再以 AES Key 解開 Data。

不過,即使綜合兩篇文章,似乎仍沒有完整說明驗證加解密過程。

但我們要知道密鑰交換的密鑰,也應當把它當作 Data 來看待,既然是 Data,應該經過加密驗證兩道手續,這裡卻只說了加解密,關於驗證,仍然要回到簽名。

回目錄

繼續閱讀|回目錄

Recheck 流程

公鑰的傳遞沒有問題,它本來就是公開的,不會因為取得公鑰而影響了資料傳送的安全性,並且所謂公私鑰,即是密鑰對,密鑰對不用來做一般資料的加解密,而是用來做密鑰的加解密。

再者,密鑰對的另一個應用即是,私鑰用來簽名,公鑰用來驗證。密鑰對應用,整理如下:

  1. 私鑰:用來簽名,或用來解密密鑰
  2. 公鑰:用來驗證簽名,或用來加密密鑰

有了兩件既定事實,我們再想想,密鑰對中的公鑰直接用來加密資料好像就可以了,但這就出問題了,因為我們沒辦法確定資料傳送方的身份,再者,如果公鑰加密的是資料,用私鑰解密大量的資料就會曠日費時,所以又回到 RSA 搭配 AES 來交換密鑰上面。

非常好,於是我們了解到 SSL/TLS 的過程,第一步是用憑證驗證身份,第二步是密鑰的交換,第三步才是資料的傳遞。

回目錄

繼續閱讀|回目錄

簽名的作用機制

X.509 憑證中有兩個重要的東西,第一個是 Public Key,第二是 Signature,我們來看看簽名如何作用。

當 Bob 要傳送資料給 Alice,這份資料透過雜湊(hash)函式產生的雜湊值加上 Bob 的 private key 產生簽名,再與憑證一起附加到資料上傳送過去。

當 Alice 收到後,用 Bob 的 Public Key 解開簽名,得到雜湊值,同樣地,Alice 也將資料透過雜湊函式產生一個雜湊值,比對這兩個雜湊值,如果相同,表示資料沒有遭到竄改。

附上來自 Wiki 的圖:

所以,簽名具有完整性(Integrity)就是這麼來的,這是資料的部份,然而,只要涉及資料的傳遞,資料加密都是必須的,這也就是說這段溝通,Bob 理應使用 Alice 的公鑰加密,或前段說的密鑰(AES Key)加密。

我們再釐清一點,事實上,前面說 RSA 的公鑰只做驗證簽名加密密鑰,所以我們把解開簽名這件事說得更清楚些,其實是這樣的,CA 將 Bob 的 Public Key 經過雜湊得到的雜湊值,用自己的 private key 產生簽名,這就是 Bob 憑證裡的簽名。

而憑證裡還有 Bob Public Key,當 Alice 收到 Bob 的憑證,會先用 root CA 中的 root Public Key 去解開 Bob 憑證中的簽名,得到了一個雜湊值,並將 Bob 憑證中的 Public Key 經過雜湊得到的雜湊值,比對剛才解開的雜湊值,確認了這是 Bob 的 Public Key。

這個 Bob 的 Public Key 才被拿去解開簽名,而解開簽名 => 比對雜湊值,這個就叫做驗證簽名

最後

最後,我們再把加密簽名合在一起,融入前述 RSA 及 AES 的密鑰交換,可能需要這麼做:

  1. Alice、Bob 分別跟 AWS 連接,此時 AWS 預產生了兩人的憑證private keyPublic Key,兩人也有在 AWS 上皆可取得的 root CA(root CA 中有 AWS 的 Public Key)。
  2. Alice、Bob 本身不需要特別保留自己的 Public Key,因為自己用不到(但自己的憑證裡包含了自己的 Public Key)。
  3. Bob 傳送資料給 AWS 時,除了附上自己的憑證,也要將資料做雜湊運算,再以自己的 private key 形成簽名並附上,即是資料憑證簽名。然而,初次連接是為了做密鑰交換,將來傳遞資料便用密鑰來做加解密(AES Key 是初次連接的資料)。
  4. 於是,由 Bob 產生 AES Key(Bob’s AES Key)後,將 Bob’s AES Key 做雜湊得到雜湊值,Bob 使用自己的 private key 加密雜湊值形成簽名,再將 AES Key 以 AWS 的 Public Key 加密
  5. Bob 傳送加密的資料(AES Key)與憑證簽名給 AWS。
  6. AWS 以自己的 Public Key 解開 Bob 憑證中的簽名,得到 Bob 的 Public Key 的雜湊值,將 Bob 憑證中的 Bob 的 Public Key 做雜湊得到雜湊值,比較兩個雜湊值,確認了 Bob 的 Public Key。
  7. AWS 以 Bob 的 Public Key 解開簽名得到資料(Bob’s AES Key)的雜湊值。
  8. AWS 以自己的 private key 解密資料(Bob’s AES Key)取得 AES Key,將 AES Key 做雜湊得到雜湊值。
  9. 比對 7 & 8 的兩個雜湊值,確認了 AES Key,至此,在這段長連接(MQTT)中,AWS 與 Bob 間都用 Bob’s AES Key 加密。
  10. 反過來,Alice 跟 AWS 間也做了相同的密鑰交換,AWS 也有了 Alice’s AES Key。
  11. Bob 傳送以 Bob’s AES Key 加密的資料到 AWS,AWS 以 Bob’s AES Key 解開資料。
  12. AWS 傳送以 Alice’s AES Key 加密的資料到 Alice,Alice 也以 Alice’s AES Key 解開資料,得到 Bob 當初發出的資料。

如果是這種方式,所謂的 Bob’s AES Key、Alice’s AES Key,這個 AES Key 叫做 Session Key,而因為密鑰是安全地被交換,即便攔截到訊息,也沒那麼容易被解開,這就是 SSL/TLS 的作用原理。

最後的最後

最後的最後,我們再來看看如果 Bob 要跟 Alice 直接溝通的話,可能需要這麼做:

  1. Alice、Bob 分別跟 AWS 連接,此時 AWS 預產生了兩人的憑證private keyPublic Key,兩人也有在 AWS 上皆可取得的 root CA(root CA 中有 AWS 的 Public Key)。
  2. Alice、Bob 本身不需要特別保留自己的 Public Key,因為自己用不到(但自己的憑證裡包含了自己的 Public Key)。
  3. Bob 傳送資料給 Alice,除了自己的憑證,也要將資料做雜湊運算,再以自己的 private key 形成簽名
  4. Bob 將資料附上憑證簽名傳給 Alice。
  5. Alice 收到後,使用 root Public Key 解開 Bob 憑證中的簽名,得到 Bob 的 Public Key 的雜湊值,也將憑證中 Bob 的 Public Key 做雜湊得到雜湊值,比對雜湊值,確認了 Bob 的 Public Key。
  6. Alice 再以 Bob 的 Public Key 解開簽名,得到資料的雜湊值;將得到的資料也做雜湊得到雜湊值,比對兩個雜湊值,確認了 Bob 的資料。
  7. 反之亦然。

呼——!大致是這樣,不過,若真是以這種方式進行,資料其實沒有加密,因為 Bob 不會提前知道 Alice 的公鑰,所以可能的做法是初次連接做非資料的傳遞,確認了彼此的公鑰,再做 AES Key 的交換。

在這篇,我們引入了密鑰的交換方法,下次再來研究所謂的 Diffie–Hellman 密鑰交換,這次就分享到這,感謝您的閱讀。

回目錄

繼續閱讀|回目錄

Reference:

--

--

春麗 S.T.E.M.
春麗 S.T.E.M.

Written by 春麗 S.T.E.M.

Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage, against the dying of the light.

No responses yet