-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.py
156 lines (127 loc) · 5.68 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
148
149
150
151
152
153
154
155
156
# This is a client
import blowfish
import random
import ecdsa
import hashlib
class Client():
def __init__(self, server, ec):
"""
This function initializes the client and its processes,
including login and proceeding to order the cookies.
"""
print("\n", "-"*24, "\n")
self.ec = ec
self.username = ""
# Key Exchange
self.key_exchange(server)
print("Key Exchange Successful!\n\n", "-"*24, "\n")
# Login Form
self.login(server)
print("\nLogin Successful!\n\n", "-"*24, "\n\n")
# Payment Form
self.pay(server)
def key_exchange(self, server):
"""
This function calls all of the relevant key exchange functions,
including private, public, shared and blowfish keys.
"""
self.generate_keys()
self.generate_shared_key(server)
self.blowfish_key_exchange(server)
def generate_keys(self):
"""
This function generates a private and public keys.
"""
self.private_key = random.randint(1, self.ec.Prime)
self.public_key = self.ec.mul(self.ec.G, self.private_key)
def generate_shared_key(self, server):
"""
This function generates a shared key.
"""
signature = ecdsa.Ecdsa.sign(
self.ec, self.public_key, self.private_key)
# returned_public_key from server
returned_public_key, returned_signature = server.generate_shared_key(
self.public_key, signature)
self.Qa = returned_public_key
self.verify_signature(
returned_public_key, returned_signature, "Public Key from Server")
self.shared_key = self.ec.mul(returned_public_key, self.private_key)
print("Generated Shared Key:\t\t", self.shared_key.x)
print("\t\t\t\t", self.shared_key.y, "\n\n", "-"*24, "\n")
def blowfish_key_exchange(self, server):
"""
This function requests performing key exchange for blowfish.
"""
# Randomly Generated 64-bit Blowfish Input Key
self.blowfish_key = random.randint(2**54, 2**64 - 1)
# Generate an Encryption Key for the Blowfish Key
bfkey_encryption_key = blowfish.Blowfish.generate_input_key(
self.shared_key.y)
bf = blowfish.Blowfish(bfkey_encryption_key)
# It will be encrypted by the public key of elliptic curve
# Before it will be sent to the server
key_encrypted = bf.encryption(self.blowfish_key)
print("Blowfish Key before Encryption:\t", self.blowfish_key)
print("Encrypted Blowfish Key:\t\t", key_encrypted)
print("\nSent to server authentication ... \nAwaiting response ... \n")
signature = ecdsa.Ecdsa.sign(
self.ec, key_encrypted, self.private_key)
server.validate_blowfish_key_exchange(key_encrypted, signature)
def login(self, server):
"""
This function takes care of a login loop until valid parameters are inputted.
"""
validation_success = False
while (validation_success is False):
if (self.username is not ""):
print("\nLogin Failed!\nInvalid username or password - try again\n")
username, password = self.login_prompt()
print("\nSent to server authentication ... \nAwaiting response ... \n")
signature = ecdsa.Ecdsa.sign(
self.ec, username + password, self.private_key)
validation_success = server.validate_credentials(
username, password, signature)
def login_prompt(self):
"""
This function prompts a login form,
and hashes the inputted password with a sha-256 hash.
"""
self.username = input("Enter Username: ")
input_password = self.sha256(input("Enter Password: "))
self.password = ''.join(str(w) for w in input_password)
return self.username, self.password
def pay(self, server):
"""
This function requests performing a payment.
It encrypts the data using blowfish,
and also signs it to verify authenticity later on.
"""
bf_key = blowfish.Blowfish.generate_input_key(self.blowfish_key)
bf = blowfish.Blowfish(bf_key)
credit_card = bf.encryption(int(input("Please Enter Credit Card:\t ")))
security_code = bf.encryption(
int(input("Please Enter Security Code:\t ")))
amount = int(input("Amount of Cookies Wanted:\t "))
print("Encrypted Credit Card:\t\t", credit_card)
print("Encrypted Security Code:\t", security_code)
print("\nSent to server authentication ... \nAwaiting response ... \n")
signature = ecdsa.Ecdsa.sign(
self.ec, credit_card + security_code, self.private_key)
server.validate_payment(credit_card, security_code, amount, signature)
def verify_signature(self, message, signature, purpose):
"""
This function calls the ECDSA verify function with required parameters,
and prints the result. If the result is false, it exists with code 1.
"""
result = ecdsa.Ecdsa.verify(
self.ec, message, signature, self.Qa)
if (result is True):
print(
"ECDSA Check Passed Successfully! -", purpose)
else:
print(
"Invalid Signature - Elliptic Curve Digital Signature Algorithm (ECDSA) -", purpose)
exit(1)
def sha256(self, input_string):
return hashlib.sha256(str(input_string).encode('utf-8')).hexdigest()