Python Language
Socklar och meddelandekryptering / dekryptering mellan klient och server
Sök…
Introduktion
Kryptografi används för säkerhetsändamål. Det finns inte så många exempel på kryptering / dekryptering i Python med IDEA-kryptering MODE CTR. Syftet med denna dokumentation:
Utöka och implementera RSA Digital Signature-schema i kommunikation från station till station. Att använda Hashing för integritet av meddelanden, det är SHA-1. Skapa enkelt Key Transport-protokoll. Kryptera nyckel med IDEA-kryptering. Mode of Block Cipher är Counter Mode
Anmärkningar
Använd språk: Python 2.7 (nedladdningslänk: https://www.python.org/downloads/ )
Använd bibliotek:
* PyCrypto (nedladdningslänk: https://pypi.python.org/pypi/pycrypto )
* PyCryptoPlus (nedladdningslänk: https://github.com/doegox/python-cryptoplus )
Bibliotekinstallation:
PyCrypto: Packa upp filen. Gå till katalogen och öppna terminalen för Linux (alt + ctrl + t) och CMD (skift + högerklicka + välj kommandotolken öppna här) för windows. Efter det skriv python setup.py installera (Make Sure Python Environment är korrekt inställd i Windows OS)
PyCryptoPlus: Samma som det senaste biblioteket.
Genomförande av uppgifter : Uppgiften är uppdelad i två delar. En är handskakningsprocess och en annan är kommunikationsprocess. Socket Setup:
Som skapande av offentliga och privata nycklar samt hashning av den offentliga nyckeln måste vi konfigurera uttaget nu. För att ställa in socket måste vi importera en annan modul med “import socket” och ansluta (för klient) eller binda (för server) IP-adressen och porten med socket som kommer från användaren.
----------Klientsidan----------
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))
---------- Server sida ---------
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-----"
"Socket.AF_INET, socket.SOCK_STREAM" tillåter oss att använda accept () -funktion och meddelandegrunder. I stället för det kan vi använda “socket.AF_INET, socket.SOCK_DGRAM” också men den tiden måste vi använda setblocking (värde).
Handskakningsprocess:
- (KLIENT) Den första uppgiften är att skapa en offentlig och privat nyckel. För att skapa den privata och offentliga nyckeln måste vi importera några moduler. De är: från Crypto-import slumpmässigt och från Crypto.PublicKey-import RSA. För att skapa nycklarna måste vi skriva några enkla koder:
random_generator = Random.new().read
key = RSA.generate(1024,random_generator)
public = key.publickey().exportKey()
random_generator härrör från " från Crypto import Random " -modulen. Nyckel härrör från " från Crypto.PublicKey import RSA " som skapar en privat nyckel, storlek 1024 genom att generera slumpmässiga tecken. Public exporterar offentlig nyckel från tidigare genererad privat nyckel.
(KLIENT) Efter att ha skapat den offentliga och privata nyckeln måste vi hash den offentliga nyckeln för att skicka över till servern med SHA-1-hash. För att använda SHA-1-hash måste vi importera en annan modul genom att skriva "import hashlib". För att hash den offentliga nyckeln har vi skrivit två kodrader:
hash_object = hashlib.sha1(public) hex_digest = hash_object.hexdigest()
Här hash_object och hex_digest är vår variabel. Efter detta kommer klienten att skicka hex_digest och public till servern och servern kommer att verifiera dem genom att jämföra hash från klient och ny hash av den offentliga nyckeln. Om den nya hash och hash från klienten matchar kommer den att gå till nästa procedur. Eftersom allmänheten som skickas från klienten är i form av sträng kan den inte användas som nyckel på serversidan. För att förhindra detta och konvertera strängnyckel till rsa offentlig nyckel måste vi skriva server_public_key = RSA.importKey(getpbk)
, här getpbk är den offentliga nyckeln från klienten.
(SERVER) Nästa steg är att skapa en sessionnyckel. Här har jag använt "os" -modul för att skapa en slumpmässig nyckel "key = os.urandom (16)" som ger oss en 16bit lång nyckel och efter det har jag krypterat den nyckeln i "AES.MODE_CTR" och hash den igen med 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()
Så en_digest kommer att vara vår sessionnyckel.
(SERVER) För den sista delen av handskakningsprocessen är att kryptera den offentliga nyckeln från klienten och sessionnyckeln som skapats på serversidan.
#encrypting session key and public key E = server_public_key.encrypt(encrypto,16)
Efter kryptering skickar servern nyckeln till klienten som sträng.
(CLIENT) Efter att ha fått den krypterade strängen (public och sessionnyckel) från servern, kommer klienten att dekryptera dem med hjälp av Private Key som skapades tidigare tillsammans med den offentliga nyckeln. Eftersom den krypterade (offentliga och session nyckeln) var i form av sträng, nu måste vi få tillbaka den som en nyckel genom att använda eval (). Om dekrypteringen är klar är handskakningsprocessen avslutad också eftersom båda sidor bekräftar att de använder samma tangenter. Så här dekrypteras:
en = eval(msg) decrypt = key.decrypt(en) # hashing sha1 en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest()
Jag har använt SHA-1 här så att den är läsbar i utgången.
Kommunikationsprocess:
För kommunikationsprocessen måste vi använda sessionsknappen från båda sidorna som KEY for IDEA-kryptering MODE_CTR. Båda sidorna kommer att kryptera och dekryptera meddelanden med IDEA.MODE_CTR med sessionsknappen.
(Kryptering) För IDEA-kryptering behöver vi en nyckel på 16 bit i storlek och räknare som måste kallas in. Räknaren är obligatorisk i MODE_CTR. Sessionnyckeln som vi krypterade och hashade är nu storleken 40 som kommer att överskrida gränsknappen för IDEA-krypteringen. Därför måste vi minska storleken på sessionsknappen. För att minska kan vi använda normal python inbyggd funktionssträng [värde: värde]. Där värdet kan vara valfritt värde beroende på användarens val. I vårt fall har jag gjort "nyckel [: 16]" där det kommer att ta från 0 till 16 värden från nyckeln. Denna konvertering kan göras på många sätt som nyckel [1:17] eller nyckel [16:]. Nästa del är att skapa en ny IDEA-krypteringsfunktion genom att skriva IDEA.new () som tar 3 argument för bearbetning. Det första argumentet kommer att vara KEY, det andra argumentet är läget för IDEA-krypteringen (i vårt fall IDEA.MODE_CTR) och det tredje argumentet kommer att vara räknaren = som är en måste utrullningsbar funktion. Räknaren = har en strängstorlek som kommer att returneras av funktionen. För att definiera räknaren = måste vi använda ett rimligt värde. I det här fallet har jag använt storleken på KEY genom att definiera lambda. I stället för att använda lambda kan vi använda Counter.Util som genererar slumpmässigt värde för räknare =. För att kunna använda Counter.Util måste vi importera räknemodulen från krypto. Därför kommer koden att vara:
ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
När vi definierat “ideaEncrypt” som vår IDEA-krypteringsvariabel kan vi använda den inbyggda krypteringsfunktionen för att kryptera alla meddelanden.
eMsg = ideaEncrypt.encrypt(whole)
#converting the encrypted message to HEXADECIMAL to readable eMsg =
eMsg.encode("hex").upper()
I detta kodesegment är hela meddelandet som ska krypteras och eMsg är det krypterade meddelandet. Efter att ha krypterat meddelandet har jag konverterat det till HEXADECIMAL för att göra läsbart och övre () är den inbyggda funktionen för att göra tecknen med stora bokstäver. Därefter skickas det krypterade meddelandet till motsatt station för dekryptering.
- (Dekryptering)
För att dekryptera de krypterade meddelandena, måste vi skapa en annan krypteringsvariabel med samma argument och samma nyckel, men den här gången kommer variabelen att dekryptera de krypterade meddelandena. Koden för samma sak som förra gången. Innan vi dekrypterar meddelandena måste vi dock avkoda meddelandet från hexadecimalt eftersom vi i vår krypteringsdel kodade det krypterade meddelandet i hexadecimalt för att bli läsbart. Därför kommer hela koden att vara:
decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key)
dMsg = ideaDecrypt.decrypt(decoded)
Dessa processer kommer att göras både på serversidan och klientsidan för kryptering och dekryptering.
Implementering av serversidan
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")
Kundens sida Implementering
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()