import random, base64, socket, os, sys, getopt
def xor_crypt(message, key):
for k in key:
new_message = ''
for m in message:
new_message += chr(ord(k)^ord(m))
message = new_message
return message
def get_key():
# Natuerlich steht der geheime Schluessel nicht hier.
# Diese Prozedur liest den Schluessel aus einem
# Truecrypt-Container, welcher mit einem Passwort
# geschuetzt ist, welches mind. 30 Zeichen lang ist.
# Zu Testzwecken wird hier einfach ein Passwort
# zurueckgegeben
return 'secretpassword'
class Server:
def __init__(self):
self.HOST = ''
self.PORT = 1337
self.ADDRESS = (self.HOST, self.PORT)
self.server = socket.socket()
self.server.bind(self.ADDRESS)
self.server.listen(1)
#
# Authentifizierungsprotokoll:
# Authentifiziert Server (S) und Client (C) ueber einen bekannten Schluessel k
# weiter wird ein neuer Schluessel vom Server generiert, der fuer die Kommunikation
# genutzt werden muss. Auf diese Weise wird verhindert, dass zuviele Nachrichten,
# die mit k verschluesselt sind, ausgetauscht werden und so die Angriffsflaeche fuer
# Kryptoanalysen minimiert.
#
# C -> S: user + nonceC
# S -> C: encrypt(nonceC, k) + encrypt(neuerSchluessel, k) + encrypt(nonceS, k)
# C -> S: encrypt(nonceS, neuerSchluessel)
key = get_key()
conn, addr = self.server.accept()
print 'Connected by', addr
data = conn.recv(1024)
user,nonceC = data.split(';')
user = base64.standard_b64decode(user)
nonceC = base64.standard_b64decode(nonceC)
encrypt_nonceC = base64.standard_b64encode(xor_crypt(nonceC, key))
new_key = str(os.urandom(random.randrange(5,10)))
encrypt_new_key = base64.standard_b64encode(xor_crypt(new_key, key))
nonceS = str(random.randrange(pow(2,32)))
tmp_nonceS = base64.standard_b64encode(xor_crypt(nonceS, key))
conn.send(encrypt_nonceC+';'+encrypt_new_key+';'+tmp_nonceS)
data = conn.recv(1024)
if nonceS == xor_crypt(base64.standard_b64decode(data), new_key):
msg = xor_crypt(user + ' ist mein Meister', new_key)
else:
msg = xor_crypt('geh weg!!!', new_key)
conn.send(base64.standard_b64encode(msg))
conn.close()
self.server.close()
class Client:
def __init__(self):
self.HOST = '127.0.0.1'
self.PORT = 1337
self.ADDRESS = (self.HOST, self.PORT)
self.client = socket.socket()
self.client.connect(self.ADDRESS)
key = get_key()
user = base64.standard_b64encode('alex')
nonceC = str(random.randrange(pow(2,32)))
tmp = base64.standard_b64encode(nonceC)
self.client.send(user+';'+tmp)
data = self.client.recv(1024)
from_server_nonceC = xor_crypt(base64.standard_b64decode(data.split(';')[0]), key[::-1])
from_server_new_key = xor_crypt(base64.standard_b64decode(data.split(';')[1]), key[::-1])
nonceS = xor_crypt(base64.standard_b64decode(data.split(';')[2]), key[::-1])
if nonceC != from_server_nonceC:
print 'Das ist nicht unser Server!'
self.client.close()
return
self.client.send(base64.standard_b64encode(xor_crypt(nonceS, from_server_new_key)))
data = self.client.recv(1024)
print xor_crypt(base64.standard_b64decode(data), from_server_new_key)
def main(argv):
try:
opts, args = getopt.getopt(argv, "sc", [])
except getopt.GetoptError:
sys.exit(2)
for opt, arg in opts:
if opt in ("-s"):
s = Server()
elif opt == '-c':
c = Client()
else:
assert False, 'unhandled option'
if __name__ == "__main__":
main(sys.argv[1:])