Szukaj…


Wprowadzenie

Kryptografia jest używana do celów bezpieczeństwa. Nie ma tak wielu przykładów szyfrowania / deszyfrowania w Pythonie przy użyciu szyfrowania IDEA MODE CTR. Cel tej dokumentacji:

Rozszerzenie i wdrożenie schematu podpisu cyfrowego RSA w komunikacji między stacjami. Używanie funkcji mieszania w celu zapewnienia integralności wiadomości, czyli SHA-1. Opracuj prosty protokół transportu klucza. Szyfruj klucz z szyfrowaniem IDEA. Trybem szyfru blokowego jest tryb licznika

Uwagi

Używany język: Python 2.7 (Link do pobrania: https://www.python.org/downloads/ )

Wykorzystana biblioteka:

* PyCrypto (Link do pobrania: https://pypi.python.org/pypi/pycrypto )

* PyCryptoPlus (Link do pobrania: https://github.com/doegox/python-cryptoplus )

Instalacja biblioteki:

PyCrypto: Rozpakuj plik. Przejdź do katalogu i otwórz terminal dla systemu Linux (alt + ctrl + t) i CMD (Shift + kliknięcie prawym przyciskiem myszy + wybierz wiersz polecenia, otwórz tutaj) dla systemu Windows. Po tym napisz instalację python setup.py install (Make Sure Python Environment jest poprawnie ustawiony w systemie Windows)

PyCryptoPlus: Taki sam jak ostatnia biblioteka.

Realizacja zadań: zadanie jest podzielone na dwie części. Jeden to proces uzgadniania, a drugi to proces komunikacji. Konfiguracja gniazda:

  • Ponieważ tworzenie kluczy publicznych i prywatnych, a także mieszanie klucza publicznego, musimy teraz skonfigurować gniazdo. Aby skonfigurować gniazdo, musimy zaimportować kolejny moduł z „importuj gniazdo” i połączyć (dla klienta) lub powiązać (dla serwera) adres IP i port, z którym gniazdo otrzymuje od użytkownika.

    ----------Strona klienta----------

      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))
    

    ----------Po stronie serwera---------

      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” pozwoli nam korzystać z funkcji accept () i podstaw komunikatora. Zamiast tego możemy również użyć „socket.AF_INET, socket.SOCK_DGRAM”, ale tym razem będziemy musieli użyć setblocking (wartość).

Proces uzgadniania:

  • (KLIENT) Pierwszym zadaniem jest utworzenie klucza publicznego i prywatnego. Aby utworzyć klucz prywatny i publiczny, musimy zaimportować niektóre moduły. Są to: z importu Crypto Random oraz z importu Crypto.PublicKey RSA. Aby utworzyć klucze, musimy napisać kilka prostych wierszy kodów:
random_generator = Random.new().read
        key = RSA.generate(1024,random_generator) 
        public = key.publickey().exportKey()

random_generator pochodzi z modułu „ z Crypto import Random ”. Klucz pochodzi od „ z Crypto.PublicKey import RSA ”, który utworzy klucz prywatny o rozmiarze 1024 poprzez generowanie losowych znaków. Public eksportuje klucz publiczny z wcześniej wygenerowanego klucza prywatnego.

  • (KLIENT) Po utworzeniu klucza publicznego i prywatnego musimy zaszyfrować klucz publiczny, aby wysłać go na serwer za pomocą skrótu SHA-1. Aby użyć skrótu SHA-1, musimy zaimportować inny moduł, pisząc „import hashlib”. Aby zaszyfrować klucz publiczny, musimy napisać dwa wiersze kodu:

      hash_object = hashlib.sha1(public) 
      hex_digest = hash_object.hexdigest()
    

Tutaj hash_object i hex_digest to nasza zmienna. Następnie klient wyśle hex_digest i public na serwer, a serwer zweryfikuje je, porównując skrót uzyskany od klienta i nowy skrót klucza publicznego. Jeśli nowy skrót i skrót od klienta są zgodne, nastąpi przejście do następnej procedury. Ponieważ publiczna wiadomość wysłana od klienta ma postać ciągu, nie będzie mogła być używana jako klucz po stronie serwera. Aby temu zapobiec i przekonwertować ciąg klucza publicznego na klucz publiczny rsa, musimy napisać server_public_key = RSA.importKey(getpbk) , tutaj getpbk jest kluczem publicznym od klienta.

  • (SERWER) Następnym krokiem jest utworzenie klucza sesji. Tutaj użyłem modułu „os” do stworzenia losowego klucza „key = os.urandom (16)”, który da nam 16-bitowy klucz, a następnie zaszyfrowałem ten klucz w „AES.MODE_CTR” i ponownie go zaszyfrowałem z 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()
    

Zatem en_digest będzie naszym kluczem do sesji.

  • (SERWER) Ostatnią częścią procesu uzgadniania jest szyfrowanie klucza publicznego uzyskanego od klienta i klucza sesji utworzonego po stronie serwera.

     #encrypting session key and public key
     E = server_public_key.encrypt(encrypto,16)
    

Po zaszyfrowaniu serwer wyśle klucz do klienta jako ciąg znaków.

  • (KLIENT) Po pobraniu zaszyfrowanego ciągu (klucza publicznego i klucza sesji) z serwera, klient odszyfruje je za pomocą klucza prywatnego, który został wcześniej utworzony wraz z kluczem publicznym. Ponieważ zaszyfrowany (klucz publiczny i klucz sesji) był w postaci łańcucha, teraz musimy go odzyskać jako klucz za pomocą eval (). Jeśli odszyfrowanie zostanie wykonane, proces uzgadniania zostanie zakończony, ponieważ obie strony potwierdzą, że używają tych samych kluczy. Aby odszyfrować:

     en = eval(msg)
     decrypt = key.decrypt(en)
     # hashing sha1
     en_object = hashlib.sha1(decrypt) en_digest = en_object.hexdigest()
    

Użyłem tutaj SHA-1, aby był czytelny na wyjściu.

Proces komunikacji:

Do procesu komunikacji musimy użyć klucza sesji z obu stron jako KLUCZA do szyfrowania IDEA MODE_CTR. Obie strony będą szyfrować i deszyfrować wiadomości za pomocą IDEA.MODE_CTR za pomocą klucza sesji.

  • (Szyfrowanie) Do szyfrowania IDEA potrzebujemy klucza o rozmiarze 16 bitów i licznika, jak trzeba wywołać. Licznik jest obowiązkowy w MODE_CTR. Klucz sesji, który zaszyfrowaliśmy i zaszyfrowaliśmy, ma teraz rozmiar 40, co przekroczy klucz limitu szyfrowania IDEA. Dlatego musimy zmniejszyć rozmiar klucza sesji. Do redukcji możemy użyć normalnego wbudowanego Pythona ciąg funkcji [wartość: wartość]. Gdzie wartością może być dowolna wartość zgodnie z wyborem użytkownika. W naszym przypadku zrobiłem „klucz [: 16]”, gdzie zajmie od 0 do 16 wartości z klucza. Tę konwersję można wykonać na wiele sposobów, np. Kluczem [1:17] lub kluczem [16:]. Następną częścią jest utworzenie nowej funkcji szyfrowania IDEA, pisząc IDEA.new (), która zajmie 3 argumenty do przetworzenia. Pierwszym argumentem będzie KEY, drugim argumentem będzie tryb szyfrowania IDEA (w naszym przypadku IDEA.MODE_CTR), a trzecim argumentem będzie counter = co jest funkcją wymaganą do wywołania. Licznik = będzie przechowywać rozmiar ciągu znaków, który zostanie zwrócony przez funkcję. Aby zdefiniować licznik =, musimy użyć rozsądnych wartości. W tym przypadku użyłem rozmiaru KLUCZA, definiując lambda. Zamiast używać lambda, możemy użyć Counter.Util, który generuje losową wartość dla counter =. Aby użyć Counter.Util, musimy zaimportować moduł licznika z krypto. Dlatego kod będzie:

      ideaEncrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda : key)
    

Po zdefiniowaniu „ideaEncrypt” jako naszej zmiennej szyfrowania IDEA, możemy użyć wbudowanej funkcji szyfrowania do zaszyfrowania dowolnej wiadomości.

eMsg = ideaEncrypt.encrypt(whole)
#converting the encrypted message to HEXADECIMAL to readable eMsg =         
eMsg.encode("hex").upper()

W tym segmencie kodu cała wiadomość jest do zaszyfrowania, a eMsg to wiadomość zaszyfrowana. Po zaszyfrowaniu wiadomości przekonwertowałem ją na HEXADECIMAL, aby była czytelna, a upper () to wbudowana funkcja umożliwiająca pisanie wielkich liter. Następnie ta zaszyfrowana wiadomość zostanie wysłana do przeciwnej stacji w celu odszyfrowania.

  • (Deszyfrowanie)

Aby odszyfrować zaszyfrowane wiadomości, będziemy musieli utworzyć inną zmienną szyfrowania przy użyciu tych samych argumentów i tego samego klucza, ale tym razem zmienna odszyfruje zaszyfrowane wiadomości. Kod tego samego co ostatnio. Jednak przed odszyfrowaniem wiadomości musimy odkodować wiadomość w systemie szesnastkowym, ponieważ w naszej części szyfrowania zakodowaliśmy zaszyfrowaną wiadomość w systemie szesnastkowym, aby była czytelna. Stąd cały kod będzie:

decoded = newmess.decode("hex")
ideaDecrypt = IDEA.new(key, IDEA.MODE_CTR, counter=lambda: key) 
dMsg = ideaDecrypt.decrypt(decoded)

Procesy te będą wykonywane zarówno po stronie serwera, jak i klienta w celu szyfrowania i deszyfrowania.

Wdrożenie po stronie serwera

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")

Wdrożenie po stronie klienta

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()


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow