Diffie-Hellman 密钥交换中的中间人攻击
先决条件: Diffie-Hellman 算法
Diffie-Hellman 密钥交换算法是一种高级密码方法,用于建立共享秘密(或共享秘密密钥),可用于在 Alice 和 Bob 之间在公共网络上进行秘密通信,同时防止 Eve(窃听者)窃听他们所有的交流,都来自学习生成的秘密。
密钥交换过程有两个步骤:
- 一次性设置:我们定义了一些所有人永远使用的公共参数。
- 协议:要生成新的密钥,请运行两个消息的密钥交换协议。这个过程是使用一些简单的代数、素数和模算术的特性来完成的。
Diffie-Hellman 的安全威胁
让我们假设窃听者 EVE 和其他人一样知道公共值 p 和 g,并且从她的窃听中,她还了解到 Alice 和 Bob、gᵃ mod p 和 gᵇ mod p 交换的值。以她所有的知识,她仍然无法计算密钥 S,事实证明,如果正确选择 p 和 g,她很难做到。
例如,您可以暴力破解它并尝试所有选项,但是当数字很大时,计算 (mod p) 会使离散对数计算变得非常慢。如果 p 和 g 有数千位,那么最著名的计算离散对数的算法虽然比简单的蛮力法快,但仍然需要数百万年的时间来计算。
即使它对蛮力免疫,它也容易受到 MITM(中间位置的人)的攻击。
中间人 (MITM) 对抗 Diffie-Hellman:
具有 MitM(中间人)位置的恶意 Malory 可以操纵 Alice 和 Bob 之间的通信,并破坏密钥交换的安全性。
此过程的分步说明:
第一步:选择公数p和g,p是素数,叫做“模数”,g叫做底。
第二步:选择私人号码。
让 Alice 选择一个私人随机数 a,让 Bob 选择一个私人随机数 b,Malory 选择 2 个随机数 c 和 d。
第三步:拦截公共价值,
Malory 拦截 Alice 的公共值 (g a (mod p)),阻止它到达 Bob,而是将她自己的公共值 (g c (modp)) 发送给 Bob,而 Malory 拦截 Bob 的公共值 (g b (mod p)),阻止它到达 Alice,而是向 Alice 发送她自己的公共价值 (g d (modp))
第 4 步:计算密钥
Alice 将计算一个密钥 S 1 =g da (mod p),而 Bob 将计算一个不同的密钥,S 2 =g cb (mod p)
第 5 步:如果 Alice 使用 S 1作为密钥来加密稍后发送给 Bob 的消息,Malory 可以对其进行解密,使用 S 2重新加密,然后将其发送给 Bob。 Bob 和 Alice 不会注意到任何问题,并可能认为他们的通信是加密的,但实际上,Malory 可以解密、读取、修改,然后重新加密他们的所有对话。
下面是实现:
Python3
import random
# public keys are taken
# p is a prime number
# g is a primitive root of p
p = int(input('Enter a prime number : '))
g = int(input('Enter a number : '))
class A:
def __init__(self):
# Generating a random private number selected by alice
self.n = random.randint(1, p)
def publish(self):
# generating public values
return (g**self.n)%p
def compute_secret(self, gb):
# computing secret key
return (gb**self.n)%p
class B:
def __init__(self):
# Generating a random private number selected for alice
self.a = random.randint(1, p)
# Generating a random private number selected for bob
self.b = random.randint(1, p)
self.arr = [self.a,self.b]
def publish(self, i):
# generating public values
return (g**self.arr[i])%p
def compute_secret(self, ga, i):
# computing secret key
return (ga**self.arr[i])%p
alice = A()
bob = A()
eve = B()
# Printing out the private selected number by Alice and Bob
print(f'Alice selected (a) : {alice.n}')
print(f'Bob selected (b) : {bob.n}')
print(f'Eve selectd private number for Alice (c) : {eve.a}')
print(f'Eve selectd private number for Bob (d) : {eve.b}')
# Generating public values
ga = alice.publish()
gb = bob.publish()
gea = eve.publish(0)
geb = eve.publish(1)
print(f'Alice published (ga): {ga}')
print(f'Bob published (gb): {gb}')
print(f'Eve published value for Alice (gc): {gea}')
print(f'Eve published value for Bob (gd): {geb}')
# Computing the secret key
sa = alice.compute_secret(gea)
sea = eve.compute_secret(ga,0)
sb = bob.compute_secret(geb)
seb = eve.compute_secret(gb,1)
print(f'Alice computed (S1) : {sa}')
print(f'Eve computed key for Alice (S1) : {sea}')
print(f'Bob computed (S2) : {sb}')
print(f'Eve computed key for Bob (S2) : {seb}')
输出:
Enter a prime number (p) : 227
Enter a number (g) : 14
Alice selected (a) : 227
Bob selected (b) : 170
Eve selectd private number for Alice (c) : 65
Eve selectd private number for Bob (d) : 175
Alice published (ga): 14
Bob published (gb): 101
Eve published value for Alice (gc): 41
Eve published value for Bob (gd): 32
Alice computed (S1) : 41
Eve computed key for Alice (S1) : 41
Bob computed (S2) : 167
Eve computed key for Bob (S2) : 167