arrow-left

All pages
gitbookPowered by GitBook
1 of 2

Loading...

Loading...

MITM

Explanation of the MITM (Man In The Middle) with the Diffie-Hellmann key exchange

Diffie-Hellman

hashtag
Overview

triangle-exclamation

We need to make some changes: separate the explanation from the code, add a subpart about the MITM and maybe to develop more the instructions

Let's say Alice and Bob want to exchange a secret over an insecure channel. In other words, anyone can read the messages they send, but the goal is to ensure that only Alice and Bob can calculate the secret key.

Diffie-Hellman key exchange provides a solution to this seemingly impossible task. Since code may be easier to understand than a detailed explanation, I'll provide it first:

Here's a brief explanation of the code:

  • We choose a prime and a generator

  • Alice picks a private key

  • Bob picks a private key

circle-info

So anybody observing the messages sent between Alice and Bob would see , but they wouldn't be able to calculate the shared key .

This is because given and , it should be infeasible to calculate . If this sounds familiar, that's because it's the .

The original paper can be found . It uses the group of integers modulo a prime to perform the key exchange. In practice however, any group with a hard discrete log problem can be used.

Alice's public key is gamod  pg^a \mod pgamodp

  • Bob's public key is gbmod  pg^b \mod pgbmodp

  • Their shared key is gab≡(ga)b≡(gb)a(modp)g^{ab} \equiv (g^a)^b \equiv (g^b)^a \pmod pgab≡(ga)b≡(gb)a(modp)

  • ppp
    g∈Fpg \in \mathbb{F}_pg∈Fp​
    a∈Zp−1a \in \mathbb{Z}_{p-1}a∈Zp−1​
    b∈Zp−1b \in \mathbb{Z}_{p-1}b∈Zp−1​
    p,g,ga,gbp, g, g^a, g^bp,g,ga,gb
    gabg^{ab}gab
    ggg
    gag^aga
    aaa
    Discrete Log Problem
    herearrow-up-right
    import Crypto.Util.number as cun
    import Crypto.Random.random as crr
    
    
    class DiffieHellman:
        def __init__(self, p: int):
            self.p = p
            self.g = 5
            self.private_key = crr.randrange(2, p-1)
    
        def public_key(self) -> int:
            return pow(self.g, self.private_key, self.p)
    
        def shared_key(self, other_public_key: int) -> int:
            return pow(other_public_key, self.private_key, self.p)
    
    
    p = cun.getPrime(512)
    alice = DiffieHellman(p)
    bob = DiffieHellman(p)
    
    shared_key = bob.shared_key(alice.public_key())
    assert shared_key == alice.shared_key(bob.public_key())