Python Language
Sockets und Nachrichtenverschlüsselung / Entschlüsselung zwischen Client und Server
Suche…
Einführung
Kryptographie wird aus Sicherheitsgründen verwendet. Es gibt nicht viele Beispiele für die Verschlüsselung / Entschlüsselung in Python mit der IDEA-Verschlüsselung MODE CTR. Ziel dieser Dokumentation:
Erweiterung und Implementierung des RSA Digital Signature-Schemas in der Stationskommunikation. Das Verwenden von Hashing für die Integrität einer Nachricht ist SHA-1. Erstellen Sie ein einfaches Schlüsseltransportprotokoll. Schlüssel mit IDEA-Verschlüsselung verschlüsseln. Der Blockcipher-Modus ist der Counter-Modus
Bemerkungen
Verwendete Sprache: Python 2.7 (Download-Link: https://www.python.org/downloads/ )
Verwendete Bibliothek:
* PyCrypto (Download-Link: https://pypi.python.org/pypi/pycrypto )
* PyCryptoPlus (Download-Link: https://github.com/doegox/python-cryptoplus )
Bibliotheksinstallation:
PyCrypto: Entpacken Sie die Datei. Wechseln Sie in das Verzeichnis, und öffnen Sie das Terminal für Linux (Alt + Strg + T) und CMD (Umschalt + Rechtsklick + Eingabeaufforderung hier öffnen) für Windows. Danach schreiben Sie python setup.py install (Stellen Sie sicher, dass die Python-Umgebung im Windows-Betriebssystem richtig eingestellt ist).
PyCryptoPlus: Entspricht der letzten Bibliothek.
Aufgaben-Implementierung: Die Aufgabe ist in zwei Teile aufgeteilt. Einer ist ein Handshake-Prozess und ein anderer ist ein Kommunikationsprozess. Socket-Setup:
Da das Erstellen öffentlicher und privater Schlüssel sowie das Hashing des öffentlichen Schlüssels erforderlich ist, müssen wir den Socket jetzt einrichten. Um das Socket einzurichten, müssen wir ein anderes Modul mit "Socket importieren" importieren und (für den Client) verbinden oder (für den Server) die IP-Adresse und den Port mit dem Socket verbinden, der vom Benutzer abgerufen wird.
---------- Client-Seite ----------
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) host = raw_input("Server Address To Be Connected -> ") port = int(input("Port of The Server -> ")) server.connect((host, port))
---------- Serverseite ---------
try: #setting up socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind((host,port)) server.listen(5) except BaseException: print "-----Check Server Address or Port-----"
Mit "socket.AF_INET, socket.SOCK_STREAM" können wir die Funktion accept () und Messaging-Grundlagen verwenden. Anstelle dessen können wir auch "socket.AF_INET, socket.SOCK_DGRAM" verwenden, aber zu diesem Zeitpunkt müssen wir setblocking (value) verwenden.
Handshake-Prozess:
- (KUNDEN) Die erste Aufgabe besteht darin, einen öffentlichen und einen privaten Schlüssel zu erstellen. Um den privaten und den öffentlichen Schlüssel zu erstellen, müssen wir einige Module importieren. Sie sind: aus Crypto-Import Random und aus Crypto.PublicKey-Import RSA. Um die Schlüssel zu erstellen, müssen wir einige einfache Codezeilen schreiben:
random_generator = Random.new().read
key = RSA.generate(1024,random_generator)
public = key.publickey().exportKey()
random_generator wird vom Modul " Crypto import Random " abgeleitet. Der Schlüssel wird von " from Crypto.PublicKey import RSA " abgeleitet, der einen privaten Schlüssel mit der Größe 1024 erstellt, indem zufällige Zeichen generiert werden. Public exportiert den öffentlichen Schlüssel aus einem zuvor generierten privaten Schlüssel.
(KUNDEN) Nachdem Sie den öffentlichen und den privaten Schlüssel erstellt haben, müssen Sie den öffentlichen Schlüssel mit einem SHA-1-Hash an den Server senden. Um den SHA-1-Hash verwenden zu können, müssen Sie ein anderes Modul importieren, indem Sie „import hashlib“ schreiben. Um den öffentlichen Schlüssel zu haschen, müssen wir zwei Codezeilen schreiben:
hash_object = hashlib.sha1(public) hex_digest = hash_object.hexdigest()
Hier ist hash_object und hex_digest unsere Variable. Danach sendet der Client hex_digest und public an den Server, und der Server überprüft sie, indem er den vom Client erhaltenen Hash und den neuen Hash des öffentlichen Schlüssels vergleicht. Wenn der neue Hash und der Hash vom Client übereinstimmen, wird zur nächsten Prozedur übergegangen. Da das vom Client gesendete Publikum in Form einer Zeichenfolge vorliegt, kann es nicht als Schlüssel auf der Serverseite verwendet werden. Um dies zu verhindern und den öffentlichen String des öffentlichen Zeichens in einen öffentlichen rsa-Schlüssel zu konvertieren, müssen Sie server_public_key = RSA.importKey(getpbk)
schreiben. Hier ist getpbk der öffentliche Schlüssel des Clients.
(SERVER) Als nächsten Schritt erstellen Sie einen Sitzungsschlüssel. Hier habe ich mit dem "os" -Modul einen zufälligen Schlüssel "key = os.urandom (16)" erstellt, der uns einen 16-Bit-langen Schlüssel geben wird. Danach habe ich diesen Schlüssel in "AES.MODE_CTR" verschlüsselt und ihn erneut hashiert mit SHA-1:
#encrypt CTR MODE session key en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128) encrypto = en.encrypt(key_128) #hashing sha1 en_object = hashlib.sha1(encrypto) en_digest = en_object.hexdigest()
Der en_digest wird also unser Sitzungsschlüssel sein.
(SERVER) Der letzte Teil des Handshake-Prozesses besteht darin, den vom Client erhaltenen öffentlichen Schlüssel und den auf dem Server erstellten Sitzungsschlüssel zu verschlüsseln.
#encrypting session key and public key E = server_public_key.encrypt(encrypto,16)
Nach der Verschlüsselung sendet der Server den Schlüssel als Zeichenfolge an den Client.
(CLIENT) Nachdem der verschlüsselte String (public und session key) vom Server abgerufen wurde, entschlüsselt der Client diese mit dem zuvor mit dem öffentlichen Schlüssel erstellten privaten Schlüssel. Da der verschlüsselte (öffentliche und Sitzungsschlüssel) in Form einer Zeichenfolge vorliegt, müssen wir ihn jetzt mithilfe von eval () als Schlüssel zurückholen. Wenn die Entschlüsselung abgeschlossen ist, ist der Handshake-Vorgang abgeschlossen, da beide Seiten bestätigen, dass sie dieselben Schlüssel verwenden. Zu entschlüsseln:
en = eval(msg) decrypt = key.decrypt(en) # hashing sha1 en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest()
Ich habe den SHA-1 hier verwendet, damit er in der Ausgabe lesbar ist.
Kommunikationsprozess:
Für den Kommunikationsprozess müssen wir den Sitzungsschlüssel von beiden Seiten als Schlüssel für die IDEA-Verschlüsselung MODE_CTR verwenden. Beide Seiten verschlüsseln und entschlüsseln Nachrichten mit IDEA.MODE_CTR unter Verwendung des Sitzungsschlüssels.
(Verschlüsselung) Für die IDEA-Verschlüsselung benötigen wir einen 16bit großen Schlüssel und einen Zähler, der aufrufbar ist. Zähler ist in MODE_CTR obligatorisch. Der von uns verschlüsselte und gehashte Sitzungsschlüssel hat jetzt eine Größe von 40, was den Grenzwert der IDEA-Verschlüsselung überschreitet. Daher müssen wir die Größe des Sitzungsschlüssels reduzieren. Zur Reduzierung können wir den in Python eingebauten Funktionsstring [value: value] verwenden. Dabei kann der Wert je nach Wahl des Benutzers ein beliebiger Wert sein. In unserem Fall habe ich "key [: 16]" vorgenommen, wobei der Schlüssel aus 0 bis 16 Werten genommen wird. Diese Konvertierung kann auf viele Arten durchgeführt werden, z. B. Schlüssel [1:17] oder Schlüssel [16:]. Der nächste Teil ist das Erstellen einer neuen IDEA-Verschlüsselungsfunktion, indem IDEA.new () geschrieben wird, das 3 Argumente für die Verarbeitung benötigt. Das erste Argument ist KEY, das zweite Argument ist der Modus der IDEA-Verschlüsselung (in unserem Fall IDEA.MODE_CTR) und das dritte Argument ist der counter =, der eine aufrufbare Funktion ist. Der Zähler = enthält eine Stringgröße, die von der Funktion zurückgegeben wird. Um den Zähler zu definieren, müssen wir vernünftige Werte verwenden. In diesem Fall habe ich die Größe des Schlüssels verwendet, indem ich Lambda definiert habe. Anstatt Lambda zu verwenden, können wir Counter.Util verwenden, das einen Zufallswert für counter = generiert. Um Counter.Util verwenden zu können, müssen wir das Counter-Modul aus Crypto importieren. Daher lautet der Code:
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
Nachdem wir "ideaEncrypt" als IDEA-Verschlüsselungsvariable definiert haben, können wir die integrierte Verschlüsselungsfunktion verwenden, um jede Nachricht zu verschlüsseln.
eMsg = ideaEncrypt.encrypt(whole)
#converting the encrypted message to HEXADECIMAL to readable eMsg =
eMsg.encode("hex").upper()
In diesem Codesegment ist "Ganz" die zu verschlüsselnde Nachricht und "eMsg" die verschlüsselte Nachricht. Nach dem Verschlüsseln der Nachricht habe ich sie in HEXADECIMAL konvertiert, um sie lesbar zu machen, und upper () ist die eingebaute Funktion, um die Zeichen in Großbuchstaben zu schreiben. Danach wird diese verschlüsselte Nachricht zur Entschlüsselung an die Gegenstation gesendet.
- (Entschlüsselung)
Um die verschlüsselten Nachrichten zu entschlüsseln, müssen Sie eine weitere Verschlüsselungsvariable erstellen, indem Sie dieselben Argumente und denselben Schlüssel verwenden. Diesmal entschlüsselt die Variable jedoch die verschlüsselten Nachrichten. Der Code hierfür entspricht dem letzten Mal. Vor dem Entschlüsseln der Nachrichten müssen wir die Nachricht jedoch hexadezimal decodieren, da in unserem Verschlüsselungsteil die verschlüsselte Nachricht hexadezimal codiert wurde, um lesbar zu sein. Daher wird der gesamte Code sein:
decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key)
dMsg = ideaDecrypt.decrypt(decoded)
Diese Prozesse werden sowohl auf der Server- als auch auf der Clientseite zum Verschlüsseln und Entschlüsseln ausgeführt.
Serverseitige Implementierung
import socket
import hashlib
import os
import time
import itertools
import threading
import sys
import Crypto.Cipher.AES as AES
from Crypto.PublicKey import RSA
from CryptoPlus.Cipher import IDEA
#server address and port number input from admin
host= raw_input("Server Address - > ")
port = int(input("Port - > "))
#boolean for checking server and port
check = False
done = False
def animate():
for c in itertools.cycle(['....','.......','..........','............']):
if done:
break
sys.stdout.write('\rCHECKING IP ADDRESS AND NOT USED PORT '+c)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\r -----SERVER STARTED. WAITING FOR CLIENT-----\n')
try:
#setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind((host,port))
server.listen(5)
check = True
except BaseException:
print "-----Check Server Address or Port-----"
check = False
if check is True:
# server Quit
shutdown = False
# printing "Server Started Message"
thread_load = threading.Thread(target=animate)
thread_load.start()
time.sleep(4)
done = True
#binding client and address
client,address = server.accept()
print ("CLIENT IS CONNECTED. CLIENT'S ADDRESS ->",address)
print ("\n-----WAITING FOR PUBLIC KEY & PUBLIC KEY HASH-----\n")
#client's message(Public Key)
getpbk = client.recv(2048)
#conversion of string to KEY
server_public_key = RSA.importKey(getpbk)
#hashing the public key in server side for validating the hash from client
hash_object = hashlib.sha1(getpbk)
hex_digest = hash_object.hexdigest()
if getpbk != "":
print (getpbk)
client.send("YES")
gethash = client.recv(1024)
print ("\n-----HASH OF PUBLIC KEY----- \n"+gethash)
if hex_digest == gethash:
# creating session key
key_128 = os.urandom(16)
#encrypt CTR MODE session key
en = AES.new(key_128,AES.MODE_CTR,counter = lambda:key_128)
encrypto = en.encrypt(key_128)
#hashing sha1
en_object = hashlib.sha1(encrypto)
en_digest = en_object.hexdigest()
print ("\n-----SESSION KEY-----\n"+en_digest)
#encrypting session key and public key
E = server_public_key.encrypt(encrypto,16)
print ("\n-----ENCRYPTED PUBLIC KEY AND SESSION KEY-----\n"+str(E))
print ("\n-----HANDSHAKE COMPLETE-----")
client.send(str(E))
while True:
#message from client
newmess = client.recv(1024)
#decoding the message from HEXADECIMAL to decrypt the ecrypted version of the message only
decoded = newmess.decode("hex")
#making en_digest(session_key) as the key
key = en_digest[:16]
print ("\nENCRYPTED MESSAGE FROM CLIENT -> "+newmess)
#decrypting message from the client
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key)
dMsg = ideaDecrypt.decrypt(decoded)
print ("\n**New Message** "+time.ctime(time.time()) +" > "+dMsg+"\n")
mess = raw_input("\nMessage To Client -> ")
if mess != "":
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
eMsg = ideaEncrypt.encrypt(mess)
eMsg = eMsg.encode("hex").upper()
if eMsg != "":
print ("ENCRYPTED MESSAGE TO CLIENT-> " + eMsg)
client.send(eMsg)
client.close()
else:
print ("\n-----PUBLIC KEY HASH DOESNOT MATCH-----\n")
Client-seitige Implementierung
import time
import socket
import threading
import hashlib
import itertools
import sys
from Crypto import Random
from Crypto.PublicKey import RSA
from CryptoPlus.Cipher import IDEA
#animating loading
done = False
def animate():
for c in itertools.cycle(['....','.......','..........','............']):
if done:
break
sys.stdout.write('\rCONFIRMING CONNECTION TO SERVER '+c)
sys.stdout.flush()
time.sleep(0.1)
#public key and private key
random_generator = Random.new().read
key = RSA.generate(1024,random_generator)
public = key.publickey().exportKey()
private = key.exportKey()
#hashing the public key
hash_object = hashlib.sha1(public)
hex_digest = hash_object.hexdigest()
#Setting up socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#host and port input user
host = raw_input("Server Address To Be Connected -> ")
port = int(input("Port of The Server -> "))
#binding the address and port
server.connect((host, port))
# printing "Server Started Message"
thread_load = threading.Thread(target=animate)
thread_load.start()
time.sleep(4)
done = True
def send(t,name,key):
mess = raw_input(name + " : ")
key = key[:16]
#merging the message and the name
whole = name+" : "+mess
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
eMsg = ideaEncrypt.encrypt(whole)
#converting the encrypted message to HEXADECIMAL to readable
eMsg = eMsg.encode("hex").upper()
if eMsg != "":
print ("ENCRYPTED MESSAGE TO SERVER-> "+eMsg)
server.send(eMsg)
def recv(t,key):
newmess = server.recv(1024)
print ("\nENCRYPTED MESSAGE FROM SERVER-> " + newmess)
key = key[:16]
decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key)
dMsg = ideaDecrypt.decrypt(decoded)
print ("\n**New Message From Server** " + time.ctime(time.time()) + " : " + dMsg + "\n")
while True:
server.send(public)
confirm = server.recv(1024)
if confirm == "YES":
server.send(hex_digest)
#connected msg
msg = server.recv(1024)
en = eval(msg)
decrypt = key.decrypt(en)
# hashing sha1
en_object = hashlib.sha1(decrypt)
en_digest = en_object.hexdigest()
print ("\n-----ENCRYPTED PUBLIC KEY AND SESSION KEY FROM SERVER-----")
print (msg)
print ("\n-----DECRYPTED SESSION KEY-----")
print (en_digest)
print ("\n-----HANDSHAKE COMPLETE-----\n")
alais = raw_input("\nYour Name -> ")
while True:
thread_send = threading.Thread(target=send,args=("------Sending Message------",alais,en_digest))
thread_recv = threading.Thread(target=recv,args=("------Recieving Message------",en_digest))
thread_send.start()
thread_recv.start()
thread_send.join()
thread_recv.join()
time.sleep(0.5)
time.sleep(60)
server.close()