Diffie–Hellman 函式是多數已部署公鑰協商協定的核心。然而並不存在單一個「Diffie–Hellman 協定」,而是有多種使用 DH 函式建立共享秘密的方式。
以下依慣例把雙方稱為 Alice 與 Bob,攻擊者稱為 Eve;g 是算術運算所用群的底數,Alice 與 Bob 事先知道且固定。
匿名 Diffie–Hellman#
匿名 Diffie–Hellman 是最簡單的 DH 協定。稱為匿名,是因為它未經鑑別——參與者沒有任何一方能驗證的身分,雙方也不持有長期金鑰。Alice 無法向 Bob 證明她是 Alice,反之亦然。
Alice Bob
挑隨機指數 a 挑隨機指數 b
設 A = g^a ── A ──→ 算 A^b = (g^a)^b = g^ab
算 B^a = g^ab ←── B ── 設 B = g^b
圖 11-2:匿名 Diffie–Hellman 協定
純粹、簡單——但只對最懶的攻擊者安全。
中間人攻擊#
匿名 DH 可以被中間人攻擊擊垮。竊聽者只要攔截訊息,對 Alice 假裝是 Bob、對 Bob 假裝是 Alice:
Alice 攻擊者 Eve Bob 挑隨機指數 a 挑隨機指數 b 設 A = g^a → 丟棄 A 挑隨機指數 c 送 C = g^c 給 Bob → 以為收到 Alice 的 C 算 C^b = g^bc 丟棄 B ← 設 B = g^b 算 B^c = g^bc 挑隨機指數 d 算 D^a = g^ad ← 送 D = g^d 給 Alice 算 A^d = g^ad結果:Eve 與 Alice 共享一個秘密
g^ad,與 Bob 共享另一個秘密g^bc,而 Alice 與 Bob 都以為他們彼此共享單一個秘密。協定執行完後,Alice 會從
g^ad導出對稱金鑰來加密送給 Bob 的資料,而 Eve 會攔截這些加密訊息、解密它們(可能還修改明文),再用從g^bc導出的另一組金鑰重新加密送給 Bob。這一切都在 Alice 與 Bob 毫不知情的情況下發生。
要挫敗這個攻擊,你需要一個鑑別雙方身分的方法。

圖 11-3:對匿名 Diffie–Hellman 協定的中間人攻擊
鑑別式 Diffie–Hellman#
鑑別式 Diffie–Hellman 就是為了處理匿名 DH 的中間人攻擊而發展的。它讓雙方各持有一把私鑰與一把公鑰,使 Alice 與 Bob 能簽署他們的訊息,阻止 Eve 代表他們送訊息。
這裡的簽章不是用 DH 函式計算的,而是用 RSA-PSS 這類公鑰簽章方案。
因此攻擊者要成功代表 Alice 送訊息,就得偽造一個有效簽章——這在安全的簽章方案下是不可能的。
Alice (privA, pubB) Bob (privB, pubA)
挑隨機指數 a 挑隨機指數 b
設 A = g^a
設 sigA = sign(privA, A) ── A, sigA ──→ 用 pubA 驗證 sigA
簽章無效則中止
算 A^b = g^ab
用 pubB 驗證 sigB ←── B, sigB ── 設 B = g^b
簽章無效則中止 設 sigB = sign(privB, B)
算 B^a = g^ab
圖 11-4:鑑別式 Diffie–Hellman 協定
「Alice (privA, pubB)」表示 Alice 持有自己的私鑰
privA與 Bob 的公鑰pubB。這種 priv/pub 金鑰對稱為長期金鑰,因為它事先固定,並在協定的連續執行中保持不變。
對竊聽者的安全性#
鑑別式 DH 對竊聽者是安全的——攻擊者不知道 DH 指數,因此學不到共享秘密
g^ab的任何一個位元。它也提供前向保密:即使攻擊者在某個時間點攻陷了任一方(入侵模型),他們會學到私有簽章金鑰,但學不到任何短暫的 DH 指數,因此無法得知任何先前共享秘密的值。
鑑別式 DH 也防止任一方控制共享秘密的值:Alice 無法精心構造一個特殊的 a 來預測 g^ab,因為她不控制 b,而 b 對 g^ab 的影響與 a 一樣大。
一個例外是 Alice 選
a = 0,此時對任何b都有g^ab = 1。但 0 不是被允許的值,協定應該拒絕它。
弱點一:重放#
Eve 可以錄下先前的
A與sigA,稍後重播給 Bob,藉此假裝是 Alice。Bob 就會相信自己在與 Alice 共享一個秘密——儘管 Eve 無法得知那個秘密。
解法:金鑰確認(key confirmation)——Alice 與 Bob 互相證明他們擁有該共享秘密。例如雙方分別送出:
Alice → Bob:Hash(pubA ‖ pubB, g^ab)
Bob → Alice:Hash(pubB ‖ pubA, g^ab)雙方都能用 pubA、pubB 與 g^ab 驗證這些雜湊值的正確性。
弱點二:資料外洩#
鑑別式 DH 對資料外洩攻擊者的脆弱性更值得擔憂。
在這類攻擊中,攻擊者學到短暫秘密(指數
a與b)的值,並用它冒充其中一方。若 Eve 能學到某個指數
a以及送給 Bob 的對應A與sigA,她就能發起一次新的協定執行並冒充 Alice:Eve (a, A, sigA, pubB) Bob (privB, pubA) 挑隨機指數 b ── A, sigA ──→ 用 pubA 驗證 sigA(會通過) 算 A^b = g^ab 用 pubB 驗證 sigB ←── B, sigB ── 設 B = g^b 用竊得的 a 算 B^a = g^ab 設 sigB = sign(privB, B)結果雙方擁有一個共享秘密,而 Bob 相信自己在跟 Alice 對話。
讓鑑別式 DH 能抵抗短暫秘密外洩的方法之一,是把長期金鑰整合進共享秘密的計算中,使得不知道長期秘密就無法決定共享秘密。

圖 11-5:對鑑別式 Diffie–Hellman 協定的冒充攻擊
MQV#
**Menezes–Qu–Vanstone(MQV)**協定是 DH 系協定歷史上的里程碑。它設計於 1998 年,曾被 NSA 納入 Suite B(用於保護機密資訊的演算法組合),核准用來保護最關鍵的資產。
NSA 最終捨棄了 MQV,據稱是因為它沒被使用。原因見後述。
MQV 是打了類固醇的 Diffie–Hellman。 它比鑑別式 DH 更安全,也改善了效能:
- 使用者只需送兩則訊息,彼此獨立,順序任意。
- 訊息比鑑別式 DH 更短。
- 不需要送明確的簽章或驗證訊息——換句話說,除了 DH 函式之外,你不需要額外使用簽章方案。
運作方式#
與鑑別式 DH 一樣,Alice 與 Bob 各持有一把長期私鑰與對方的長期公鑰。差別在於 MQV 的金鑰不是簽章金鑰,而是由私有指數 x 與公開值 g^x 組成。
Alice (x, Y = g^y) Bob (y, X = g^x)
挑隨機指數 a 挑隨機指數 b
設 A = g^a ── A ──→ 設 B = g^b
算 (B × Y^B)^(a+xA) ←── B ── 算 (A × X^A)^(b+yB)驗證兩邊得到同樣的值:
Alice:(B × Y^B)^(a+xA) = (g^b × (g^y)^B)^(a+xA) = (g^(b+yB))^(a+xA) = g^((b+yB)(a+xA))
Bob: (A × X^A)^(b+yB) = (g^a × (g^x)^A)^(b+yB) = (g^(a+xA))^(b+yB) = g^((a+xA)(b+yB))
圖 11-6:MQV 協定
兩者相同,都是 g^((b+yB)(a+xA))——Alice 與 Bob 共享同一個秘密。
安全性#
與鑑別式 DH 不同,MQV 無法僅靠短暫秘密外洩來攻破。
知道
a或b不會讓攻擊者判定最終的共享秘密,因為他們還需要長期私鑰才能算出它。
在最強的入侵模型下呢? 若 Eve 攻陷了 Alice 的長期私鑰 x,先前建立的共享秘密仍然安全——因為它們的計算也牽涉到 Alice 的短暫私鑰。
但 MQV 不提供完美的前向保密,因為下面這個攻擊:
假設 Eve 攔截 Alice 的
A訊息,換成她自己選的A = g^a。同時 Bob 把B送給 Alice(Eve 記下B的值)並算出共享金鑰。若 Eve 稍後攻陷了 Alice 的長期私鑰
x,她就能判定 Bob 在該工作階段所算出的金鑰——這破壞了前向保密,因為 Eve 還原了先前一次協定執行的共享秘密。
實務上這個風險可以被金鑰確認步驟消除:Alice 與 Bob 會發現他們並未共享同一把金鑰,因而在導出任何工作階段金鑰之前就中止協定。
為什麼很少人用#
儘管優雅又安全,MQV 在實務上很少被使用:
- 它曾受專利束縛,妨礙了廣泛採用。
- 實務上要把 MQV 做對,比它看起來更難。
事實上,權衡其增加的複雜度後,MQV 的安全好處相較於更簡單的鑑別式 DH,往往被認為並不划算。