You are on page 1of 7

Course Title: Cryptography and Course Code: BCSE309P

Network Security Lab


Faculty: Prof. Karthika V Slot: L55+56
Regno: 21BCE5695 Name: Ashwin M

Diffie Hellman – Man in the middle attack


Code:
Sender (Bob and Alice):
from random import randrange, getrandbits
import random
import socket

def is_prime(n, k=128):


""" Test if a number is prime
Args:
n -- int -- the number to test
k -- int -- the number of tests to do
return True if n is prime
"""
# Test if n is not even.
# But care, 2 is prime !
if n == 2 or n == 3:
return True
if n <= 1 or n % 2 == 0:
return False
# find r and s
s = 0
r = n - 1
while r & 1 == 0:
s += 1
r //= 2
# do k tests
for _ in range(k):
a = randrange(2, n - 1)
x = pow(a, r, n)
if x != 1 and x != n - 1:
j = 1
while j < s and x != n - 1:
x = pow(x, 2, n)
if x == 1:
return False
j += 1
if x != n - 1:
return False
return True
def generate_prime_candidate(length):
""" Generate an odd integer randomly
Args:
length -- int -- the length of the number to
generate, in bits
return a integer
"""
# generate random bits
p = getrandbits(length)
# apply a mask to set MSB and LSB to 1
p |= (1 << length - 1) | 1
return p
def generate_prime_number(length=12):

p = 4
# keep generating while the primality test fail
while not is_prime(p, 128):
p = generate_prime_candidate(length)
return p

g = generate_prime_number()
p = generate_prime_number()
class A:
def __init__(self):
self.n = random.randint(1, p)

def publish(self):
return (g**self.n)%p

def compute_secret(self, gb):


return (gb**self.n)%p

HOST = "127.0.0.1"
PORT = 65432

with socket.socket(socket.AF_INET, socket.SOCK_STREAM)


as s:
s.connect((HOST, PORT))

print("p: ", p)
print("g: ", g)

s.sendall(str(g).encode("utf-8") +
str(p).encode("utf-8"))
#s.sendall()

alice = A()
bob = A()

print(f'Alice selected (a) : {alice.n}')


print(f'Bob selected (b) : {bob.n}')
ga = alice.publish()
gb = bob.publish()

s.sendall(str(ga).encode("utf-8"))
s.sendall(str(gb).encode("utf-8"))

print(f'Alice published (ga): {ga}')


print(f'Bob published (gb): {gb}')
gea="b''"

while gea=="b''":
gea = str(s.recv(1024))
geb = str(s.recv(1024))

gea = int(gea[2:-1])
geb = int(geb[2:-1])

print("gea: ", gea)


print("geb: ", geb)

sa = alice.compute_secret(gea)
sb = bob.compute_secret(geb)

print(f'Alice computed (S1) : {sa}')


print(f'Bob computed (S2) : {sb}')
Receiver (Darth/Hacker):
from random import randrange, getrandbits
import random
import socket

HOST = "127.0.0.1"
PORT = 65432

class B:
def __init__(self):
self.a = random.randint(1, p)

self.b = random.randint(1, p)
self.arr = [self.a,self.b]

def publish(self, i):


return (g**self.arr[i])%p

def compute_secret(self, ga, i):


return (ga**self.arr[i])%p

with socket.socket(socket.AF_INET, socket.SOCK_STREAM)


as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print("Connected")

inp = str(conn.recv(1024))
g = int(inp[2:6])
p = int(inp[6:-1])

print("p =", p)
print("g =", g)

ga = str(conn.recv(1024))
gb = str(conn.recv(1024))

darth = B()

gea = darth.publish(0)
geb = darth.publish(1)
conn.sendall(str(gea).encode("utf-8"))
conn.sendall(str(geb).encode("utf-8"))

ga = int(ga[2:-1])
gb = int(gb[2:-1])

print("ga =", ga)


print("gb =", gb)

print(f'Darth selected private number for Alice


(c) : {darth.a}')
print(f'Darth selected private number for Bob
(d) : {darth.b}')

print(f'Darth published value for Alice (gc):


{gea}')
print(f'Darth published value for Bob (gd):
{geb}')
sea = darth.compute_secret(ga,0)

seb = darth.compute_secret(gb,1)

print(f'Darth computed key for Alice (S1) :


{sea}')
print(f'Darth computed key for Bob (S2) :
{seb}')

Output:
Sender:

Receiver:

You might also like