
这张图像以卡通风格(Alice in Wonderland 和 SpongeBob)生动地展示了 Diffie-Hellman (DH) 密钥交换协议的流程。图像分为左右两侧,分别代表 Alice 和 Bob(在这里用 SpongeBob 表示),中间通过箭头表示密钥交换和计算过程。整体结构是一个流程图,强调了协议的步骤:从双方同意公共参数开始,到生成私钥、计算公钥、交换公钥,最终计算共享密钥。
关键元素提取如下:
公共参数:双方事先同意一个大素数 P = 13 和一个生成元 G = 6(G 是 P 的原根或生成元,确保其幂次能覆盖 1 到 P-1 的所有值)。Alice 侧(左侧): 私钥(Private Key)= 5(随机生成)。公钥计算:(G^私钥) mod P = (6^5) mod 13 = 7776 mod 13 = 2。接收 Bob 的公钥后,计算共享密钥:(Bob公钥^Alice私钥) mod P = (9^5) mod 13 = 59049 mod 13 = 3。 Bob 侧(右侧): 私钥 = 4(随机生成)。公钥计算:(6^4) mod 13 = 1296 mod 13 = 9。接收 Alice 的公钥后,计算共享密钥:(2^4) mod 13 = 16 mod 13 = 3。 交换过程:双方交换公钥(Alice 发送 2,Bob 发送 9),但私钥始终保密。结果:双方独立计算出相同的共享密钥 = 3,用于后续加密通信。来源:图像底部标注 "PracticalNetworking.net",表明这是一个教育性插图,用于简化解释。图像使用颜色和钥匙图标来区分私钥(蓝色/橙色钥匙)、公钥(类似)和共享密钥(绿色钥匙),突出协议的安全性:即使公钥在公开通道交换,窃听者也难以逆推私钥或共享密钥。计算中使用了小数字(P=13)来简化演示;在实际应用中,P 和 G 会非常大以确保安全。
Diffie-Hellman 密钥交换(由 Whitfield Diffie 和 Martin Hellman 于 1976 年提出)是一种允许两个参与方在不安全的通道上安全地协商共享密钥的协议,而无需事先共享任何秘密信息。该协议基于离散对数问题的计算难度:给定 G^a mod P,求 a 是困难的(尤其当 P 很大时)。
DH 协议的核心是利用模运算和指数运算的数学性质,确保双方能得出相同结果,而不泄露私钥。以下是基于图像的逐步解释(使用图像中的参数 P=13, G=6):
同意公共参数: 双方(Alice 和 Bob)公开同意一个大素数 P(模数)和一个生成元 G(1 < G < P,且 G 是 P 的原根)。在图像中:P = 13(素数),G = 6。这些参数可以公开,因为协议的安全性不依赖于它们的保密。为什么选择素数 P 和生成元 G?因为这确保了 G 的幂次 mod P 会生成一个循环群,覆盖足够多的值,提高安全性。 生成私钥: 每个参与方独立随机生成一个私钥(大整数,通常在 2 到 P-2 之间)。Alice:私钥 a = 5。Bob:私钥 b = 4。私钥必须保密;它是协议安全的基石。 计算并交换公钥: 每个方计算自己的公钥:公钥 = (G^私钥) mod P。Alice 的公钥 A = (G^a) mod P = (6^5) mod 13。 计算过程:6^1 = 6 mod 13 = 66^2 = 36 mod 13 = 106^3 = 6*10 = 60 mod 13 = 86^4 = 6*8 = 48 mod 13 = 96^5 = 6*9 = 54 mod 13 = 2(图像显示 7776 mod 13 = 2,因为 6^5 = 7776,7776 ÷ 13 = 598 余 2)。 Bob 的公钥 B = (6^4) mod 13 = 1296 mod 13 = 9(1296 ÷ 13 = 99 余 9)。双方通过不安全通道交换公钥:Alice 发送 A=2 给 Bob,Bob 发送 B=9 给 Alice。公钥可以被窃听,但由于离散对数问题,攻击者无法从 A、G、P 快速求出 a。 计算共享密钥: 每个方使用对方的公钥和自己的私钥计算共享密钥 K。Alice:K = (B^a) mod P = (9^5) mod 13。 9^1 = 9 mod 13 = 99^2 = 81 mod 13 = 3(81 - 6*13 = 81-78=3)9^3 = 9*3 = 27 mod 13 = 19^4 = 9*1 = 9 mod 13 = 99^5 = 9*9 = 81 mod 13 = 3(图像显示 59049 mod 13 = 3,因为 9^5 = 59049,59049 ÷ 13 = 4542 余 3)。 Bob:K = (A^b) mod P = (2^4) mod 13 = 16 mod 13 = 3(2^1=2, 2^2=4, 2^3=8, 2^4=16 mod 13=3)。数学上,为什么相同?把这个流程画成PlantUML(顺序图 + 公式标注)

以下是使用Delphi语言实现的Diffie-Hellman密钥交换协议的代码演示。我将基于前述图像中的参数(P=13, G=6, Alice私钥=5, Bob私钥=4)来模拟整个过程。这是一个简单的控制台应用程序示例,假设使用Delphi 10+(支持System.Numerics.BigInteger以处理潜在的大数运算)。对于小参数如本例,我们可以用标准整数类型,但为了通用性,我加入了BigInteger支持。
这是一个完整的控制台程序。你可以复制到Delphi IDE中编译运行。它会输出Alice和Bob的公钥交换以及共享密钥计算过程。
program DiffieHellmanDemo;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.Numerics; // 用于BigInteger,支持大数运算(Delphi XE7+)
// 自定义模幂函数:计算 (base^exponent) mod modulus
function ModularExponentiation(const base, exponent, modulus: BigInteger): BigInteger;
var
result: BigInteger;
begin
result := BigInteger.One;
if modulus = BigInteger.One then
Exit(result);
var b := base mod modulus;
var exp := exponent;
while exp > BigInteger.Zero do
begin
if (exp mod 2) = BigInteger.One then
result := (result * b) mod modulus;
exp := exp shr 1; // 右移一位,等同于除以2
b := (b * b) mod modulus;
end;
Exit(result);
end;
begin
try
// 公共参数(基于图像)
var P: BigInteger := 13; // 大素数
var G: BigInteger := 6; // 生成元
// Alice侧
var AlicePrivate: BigInteger := 5; // Alice私钥
var AlicePublic: BigInteger := ModularExponentiation(G, AlicePrivate, P); // 计算公钥: G^AlicePrivate mod P
Writeln('Alice Public Key: ' + AlicePublic.ToString); // 输出: 2
// Bob侧
var BobPrivate: BigInteger := 4; // Bob私钥
var BobPublic: BigInteger := ModularExponentiation(G, BobPrivate, P); // 计算公钥: G^BobPrivate mod P
Writeln('Bob Public Key: ' + BobPublic.ToString); // 输出: 9
// 交换公钥(模拟)
// Alice接收Bob的公钥,计算共享密钥: BobPublic^AlicePrivate mod P
var AliceShared: BigInteger := ModularExponentiation(BobPublic, AlicePrivate, P);
Writeln('Alice Shared Secret: ' + AliceShared.ToString); // 输出: 3
// Bob接收Alice的公钥,计算共享密钥: AlicePublic^BobPrivate mod P
var BobShared: BigInteger := ModularExponentiation(AlicePublic, BobPrivate, P);
Writeln('Bob Shared Secret: ' + BobShared.ToString); // 输出: 3
// 验证共享密钥相同
if AliceShared = BobShared then
Writeln('Shared Secret Established Successfully: ' + AliceShared.ToString)
else
Writeln('Error: Shared Secrets Do Not Match');
Readln; // 等待输入以保持控制台窗口
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.