📜  Diffie-Hellman 密钥交换中的中间人攻击

📅  最后修改于: 2022-05-13 01:55:50.371000             🧑  作者: Mango

Diffie-Hellman 密钥交换中的中间人攻击

先决条件: Diffie-Hellman 算法

Diffie-Hellman 密钥交换算法是一种高级密码方法,用于建立共享秘密(或共享秘密密钥),可用于在 Alice 和 Bob 之间在公共网络上进行秘密通信,同时防止 Eve(窃听者)窃听他们所有的交流,都来自学习生成的秘密。

密钥交换过程有两个步骤:

  1. 一次性设置:我们定义了一些所有人永远使用的公共参数。
  2. 协议:要生成新的密钥,请运行两个消息的密钥交换协议。这个过程是使用一些简单的代数、素数和模算术的特性来完成的。

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