-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.py
147 lines (119 loc) · 3.5 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import socket #for sockets
import sys #for exit
from dh import DH
import random
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256
import base64
secret = 123456
print "ALICE'S SECRET: %d\n---------------\n" % (secret)
#Load key
alicePrivKey = RSA.importKey(open('alice.priv').read())
signer = PKCS1_v1_5.new(alicePrivKey)
bobPubKey = RSA.importKey(open('bob.pub').read())
verifier = PKCS1_v1_5.new(bobPubKey)
def signAndSend(conn, msg):
signature = signer.sign(SHA256.new(msg))
conn.sendall(msg + ',' + base64.b64encode(signature))
def verifyMsg(data):
elements = data.split(',')[:-1]
msg = ','.join(elements)
if not verifier.verify(SHA256.new(msg), base64.b64decode(data.split(',')[-1])):
print('Protocol failure! Bad RSA signature!')
sys.exit()
def getResponse(isInt = True):
data = None
while True:
#Receiving from server
data = s.recv(1024)
print 'received ' + data
verifyMsg(data)
data = ','.join(data.split(',')[:-1])
if data:
break
if not isInt: return data
return int(str(data))
def getShared(secret):
message = str(exchange.getPublic(secret))
try :
#Send the whole string
signAndSend(s, message)
#s.sendall(message)
except socket.error:
#Send failed
print 'Send failed in DH secret derivation!'
sys.exit()
k = int(exchange.getShared(secret, getResponse()))
print 'secret: %d' % (k)
return k
try:
#create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sys.exit();
print 'Socket Created'
host = 'localhost'
port = 4321
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
print 'Ip address of ' + host + ' is ' + remote_ip
#Connect to remote server
s.connect((remote_ip , port))
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
#Send some data to remote server
exchange = DH()
PRIME = exchange.getPrime()
GENERATOR = exchange.getGen()
#Step 2 of the protocol
a = exchange.getRandomElement()
k = getShared(a)
#Step 3 of the protocol
a2 = exchange.getRandomElement()
k2 = getShared(a2)
#Step 4 of the protocol
c = exchange.getRandomElement()
kc = (k ** c) % PRIME
challenge = (k2 ** secret * GENERATOR ** c) % PRIME
try:
#Set the whole string
m4 = str(kc) + ',' + str(challenge)
print 'Step 4 send: %s' % (m4)
signAndSend(s, m4)
#s.sendall(m4)
except socket.error:
#Send failed
print 'Send failed in step 4'
sys.exit()
#Step 5
challengeB = getResponse()
#Step 6
k3Partial = (((challenge * challengeB) % PRIME) ** a) % PRIME
try :
#Set the whole string
print 'Step 6 send: %d' % (k3Partial)
signAndSend(s, str(k3Partial))
#s.sendall(str(k3Partial))
except socket.error:
#Send failed
print 'Send failed in step 6'
sys.exit()
#Step 7
res = getResponse(False)
if not res or len(res.split(',')) != 2:
print 'Server disobeyed protocol by not sending two values in step 7!'
sys.exit()
kdInv = int(res.split(',')[1])
k3 = (int(res.split(',')[0]) ** a) % PRIME
print 'secret: %d' % (k3)
#Verification
if (kdInv * kc) % PRIME == k3:
print 'Secrets match!'
else:
print 'Secrets do not match!'
print 'Protocol ended successfully'