正在閱讀【網絡安全系列】你的連線不是私人連線?由中間人攻擊說起

【網絡安全系列】你的連線不是私人連線?由中間人攻擊說起

Ivan Wong

Ivan Wong

2021-09-26

Card image

「你的連線不是私人連線」?這個或許是其中一個最多人遇過,但又不明所以的警告了。不少人往往會被它嚇怕,以為將要前往的是惡意網站,馬上按上一頁離去。不過,有時候又會有人告訴你,直接按「繼續前往」就是了 (一般是公司或學校的內聯網)。究竟這個警告說的是什麼?忽略它又會否引起資安問題?其實這個警告牽涉的正是安全傳輸中的一大難題 —— 中間人攻擊 (Man-in-the-middle attack)。安全傳輸系列的第一章,將會由基礎的密鑰交換說起,講解什麼是中間人攻擊。

如何安全地交換密鑰?

交換密鑰是安全通信中很重要的一環。如果 A 要把加密的信息傳給 B,那 A 和 B 都需要有同樣的密鑰,反之亦然;而且還要確保第三者不會得悉此密鑰。預先面對面交換密鑰,固然是最安全的辦法 (假設沒有人竊聽)。但其實很多時候,通訊雙方是不認識的,而他們第一次溝通便是通過非面對面的方式進行。既然如此,A、B 雙方必須要在不安全的通信渠道下交換密鑰,而又能夠讓密鑰保密。要達到這個目的,就需要用到迪菲-赫爾曼密鑰交換 (Diffie–Hellman key exchange,下稱 D-H) 。D-H 是現今絕大部份密鑰交換協定的基礎,由 Bailey Whitfield Diffie 和 Martin Edward Hellman 於 1976 年發表,而他們亦因而獲得 2015 年的圖靈獎。

不過在解釋 D-H 之前,先要重温一下簡單的初中數學。首先是模除 (Modulo),簡單來說就是計算出一個數除以另一個數的餘數。給予兩個正整數 ,那麼 的結果就是 除以 的餘數,比如說 。另外,我們還需要動用到兩個性質 (Property):

希望大家都記得這些初中數學吧,基本上 D-H 是個很簡單的協定,只需要知道以上這些就足以理解了。那讓我舉一個例子講解 D-H 吧。現在有三個人,Alice、Bob 和 Charlie。Alice 和 Bob 只能通過不安全的通信渠道 交換密鑰,而 Charlie 則在竊聽 ,希望盜取他們的密鑰。

Figure 1: Alice 和 Bob 在不安全的通信渠道上進行 D-H,期間被 Charlie 竊聽

Figure 1: Alice 和 Bob 在不安全的通信渠道上進行 D-H,期間被 Charlie 竊聽

我們按照 Figure 1 走一次 D-H 的過程:

  1. Alice 和 Bob 先選取兩個可以公開的數字,, 這個數字可以不安全的通信渠道下交換,所以 Charlie 也會知道
  2. 接著,Alice 和 Bob 分別選取一個秘密的數字,Alice 選取 ,而 Bob 選取 ,而他們並不會告知對方所選取的數字。
  3. Alice 和 Bob 利用 ,分別運算出 ,接著通過 傳送給對方。這時,Charlie 能夠得知的,分別是 , , ,但當中並不包含密鑰。
  4. 最後,Alice 利用獲得的 算出 ,而 Bob 則算出

通過我們前段提及過的兩個 properties,我們可以得出:

  • Alice 算出了
  • Bob 算出了

看到了吧,盡管 Alice 不知道 是什麼,Bob 也不知道 是什麼,但他們還是能算出相同的 ,而這就是他們將會使用的共同密鑰了。那麼,正在竊聽的 Charlie 也能夠得出 嗎? 答案是 NO,因為 Charlie 從 中並沒有獲得 其中一個,所以無論如何,他也無法通過 或者 算出 。因此,我們利用 D-H,成功通過不安全的通信渠道交換密鑰了。

有些讀者可能會問,為什麼要加上 modulo 運算呢?這是為了保護 。如果只有 的話,其實是可以直接把 算出來的。例如 。但如果加上 modulo 運算,例如 便可能是 3, 9, 15,... (其實按照 算出來的答案都是 6),只能透過暴力計算 (Brute force) 去驗證了。

D-H 的漏洞,中間人攻擊

盡管 D-H 看起來很安全,但它有一個致命的弱點,就是無法在交換密鑰時認證雙方的身份,導致竊聽者能夠透過中間人攻擊 (Man-in-the-middle attack,下稱 MITM) 獲得訊息明文。我們用同一個例子,講解 MITM 吧。

Figure 2: Charlie 通過中間人攻擊,取得 Alice 和 Bob 通訊的明文信息,卻沒有被發現,成功瞞天過海

Figure 2: Charlie 通過中間人攻擊,取得 Alice 和 Bob 通訊的明文信息,卻沒有被發現,成功瞞天過海

我們從上面的第二步開始,此時 Charlie 已選取一個秘密數字 ,並運算出

  1. Charlie 截取 Alice 發出的 ,並向 Bob 發出 ,表示自己就是 Alice
  2. Charlie 截取 Bob 發出的 ,並向 Alice 發出 ,表示自己就是 Bob
  3. Alice 和 Bob 也被騙了,分別算出了 ,並以為這就是正確交換的密鑰,Charlie 也算出了
  4. 通訊開始,Charlie 截取 Alice 發出的訊息 ,通過 解密,得到了明文 "hello",並重新以 加密成 ,發給 Bob

如果是 Bob 發出訊息,Charlie 也同樣先解密,再重新加密發給 Alice 便可以了。總括而言,Alice 和 Bob 都被 Charlie 欺騙,以為 Charlie 是對方,並分別與 Charlie 進行了兩個不同的 D-H。 此後,Charlie 只需要繼續偽裝即可。由於 Alice 和 Bob 仍然會收到對方發出的訊息,他們並不會發現被 Charlie 竊聽了。

「你的連線不是私人連線」?說的就是中間人攻擊了

說回本文的主題,「你的連線不是私人連線」這個警告,其實就是告訴你,連線有機會受到中間人攻擊。假設你現在用瀏覽器打開 Facebook,卻發現這個警告,就代表瀏覽器無法驗證和你通訊的另一方,是否真的是 Facebook 的伺服器。為了阻止中間人攻擊,所有使用加密協定的伺服器,都會安裝一個憑證,用於證明自己的身份。這個憑證需要通過第三方簽署確認,證明伺服器的擁有者與宣示的身份相符。

Figure 3: Facebook 現在使用的憑證,便是由 DigiCert 這個第三方機構簽署的

Figure 3: Facebook 現在使用的憑證,便是由 DigiCert 這個第三方機構簽署的

如果出現「你的連線不是私人連線」這個警告,那就代表你的瀏覽器無法通過憑證驗證伺服器的身份。常見的原因不外乎有:

  • 憑證有效日期已過
  • 憑證簽署人身份不明 (並非由 DigiCert 這些可信的機構所簽署,例如自行簽發的憑證,這也是進入公司或學校的內聯網出現此警告的常見原因了)
  • 憑證宣告錯誤 (e.g. 宣告自己是 Facebook,但用的卻是 Google 的憑證)

關於加密連線的身分認證,其實還有很多東西可以探討,例如決定了什麼第三方機構簽署人是可信的「公開金鑰基礎建設」(Public Key Infrastructure,簡稱:PKI),以及它的對手,去中心化的身分認證協定 PGP (Pretty Good Privacy)。筆者未來會再寫幾篇文章,講解一下它們啊。

此文章撰寫自
Ivan Wong

Ivan Wong

@spectre

I am a software engineer, familiar with programming languages such as Go, Typescript and C++. Right now has been working as a DevOps engineer, so I'm also studying some DevOps things, mostly related to AWS and Kubernetes.

我是一名軟件工程師,比較熟悉 Go、Typescript 及 C++。目前的職位是 DevOps 工程師,所以也在學習一些 DevOps 知識,請大家多多指教!