Zoeken…


Invoering

Cryptografie wordt gebruikt voor beveiligingsdoeleinden. Er zijn niet zoveel voorbeelden van codering / decodering in Python met IDEA-codering MODE CTR. Doel van deze documentatie:

Uitbreiden en implementeren van het RSA Digital Signature-schema in communicatie tussen stations. Hashing gebruiken voor de integriteit van berichten, dat is SHA-1. Produceer eenvoudig Key Transport-protocol. Codeer sleutel met IDEA-codering. Modus van blokcodering is de tellermodus

Opmerkingen

Gebruikte taal: Python 2.7 (downloadlink: https://www.python.org/downloads/ )

Gebruikte bibliotheek:

* PyCrypto (downloadlink: https://pypi.python.org/pypi/pycrypto )

* PyCryptoPlus (downloadlink: https://github.com/doegox/python-cryptoplus )

Bibliotheek installatie:

PyCrypto: Pak het bestand uit. Ga naar de map en open terminal voor Linux (alt + ctrl + t) en CMD (shift + klik met de rechtermuisknop + selecteer opdrachtprompt hier openen) voor Windows. Schrijf daarna python setup.py install (Zorg ervoor dat Python Environment correct is ingesteld in Windows OS)

PyCryptoPlus: Hetzelfde als de laatste bibliotheek.

Taken Implementatie: De taak is verdeeld in twee delen. Een daarvan is handshake-proces en een ander is communicatieproces. Socket Setup:

  • Als het maken van openbare en privésleutels en het hashen van de openbare sleutel, moeten we de socket nu instellen. Voor het instellen van de socket moeten we een andere module met "import socket" importeren en het IP-adres en de poort met de socket van de gebruiker verbinden (voor client) of binden (voor de server).

    ----------Kant van de cliënt----------

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

    ---------- Serverzijde ---------

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

    Met "socket.AF_INET, socket.SOCK_STREAM" kunnen we de functie accept () en berichten gebruiken. In plaats daarvan kunnen we ook "socket.AF_INET, socket.SOCK_DGRAM" gebruiken, maar die keer zullen we setblocking (waarde) moeten gebruiken.

Handdruk proces:

  • (OPDRACHTGEVER) De eerste taak is om een openbare en persoonlijke sleutel te maken. Om de private en publieke sleutel te maken, moeten we enkele modules importeren. Ze zijn: van Crypto import Random en van Crypto.PublicKey import RSA. Om de sleutels te maken, moeten we enkele eenvoudige regels codes schrijven:
random_generator = Random.new().read
        key = RSA.generate(1024,random_generator) 
        public = key.publickey().exportKey()

random_generator is afgeleid van de module " from Crypto import Random ". Sleutel is afgeleid van " van Crypto.PublicKey import RSA " die een privésleutel maakt, grootte van 1024 door willekeurige tekens te genereren. Public exporteert publieke sleutel van eerder gegenereerde private sleutel.

  • (OPDRACHTGEVER) Nadat we de openbare en persoonlijke sleutel hebben gemaakt, moeten we de openbare sleutel hashen om met SHA-1-hash naar de server te verzenden. Om de SHA-1-hash te gebruiken, moeten we een andere module importeren door "import hashlib" te schrijven. Om de openbare sleutel te hashen, moeten we twee coderegels schrijven:

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

Hier is hash_object en hex_digest onze variabele. Hierna verzendt de client hex_digest en public naar de server en zal de server ze verifiëren door de hash van de client en de nieuwe hash van de publieke sleutel te vergelijken. Als de nieuwe hash en de hash van de client overeenkomen, wordt deze naar de volgende procedure verplaatst. Aangezien het door de client verzonden publiek de vorm van een string heeft, kan het niet als sleutel in de server worden gebruikt. Om dit te voorkomen en de openbare sleutel van de string te converteren naar de openbare rsa-sleutel, moeten we server_public_key = RSA.importKey(getpbk) , hier is getpbk de openbare sleutel van de client.

  • (SERVER) De volgende stap is het maken van een sessiesleutel. Hier heb ik de "os" -module gebruikt om een willekeurige sleutel "key = os.urandom (16)" te maken die ons een sleutel van 16 bit geeft en daarna heb ik die sleutel gecodeerd in "AES.MODE_CTR" en deze opnieuw gehasht met 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()
    

Dus de en_digest is onze sessiesleutel.

  • (SERVER) Voor het laatste deel van het handshake-proces is het coderen van de openbare sleutel die van de client is ontvangen en de sessiesleutel die aan de serverzijde is gemaakt.

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

Na het coderen stuurt de server de sleutel als een string naar de client.

  • (OPDRACHTGEVER) Na het ophalen van de gecodeerde tekenreeks van (openbare en sessiesleutel) van de server, zal de client ze decoderen met de privésleutel die eerder is gemaakt samen met de openbare sleutel. Omdat de gecodeerde (openbare en sessiesleutel) de vorm van een string had, moeten we deze nu terughalen als sleutel met behulp van eval (). Als de decodering is voltooid, is het handshake-proces ook voltooid omdat beide partijen bevestigen dat ze dezelfde sleutels gebruiken. Decoderen:

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

Ik heb de SHA-1 hier gebruikt, zodat deze leesbaar is in de uitvoer.

Communicatie proces:

Voor het communicatieproces moeten we de sessiesleutel van beide kanten gebruiken als de KEY voor IDEA-codering MODE_CTR. Beide partijen zullen berichten coderen en decoderen met IDEA.MODE_CTR met behulp van de sessiesleutel.

  • (Versleuteling) Voor IDEA-versleuteling hebben we een sleutel van 16bit nodig en een teller zoals nodig is. Teller is verplicht in MODE_CTR. De sessiesleutel die we hebben gecodeerd en gehasht, is nu 40 en overschrijdt de limietsleutel van de IDEA-codering. Daarom moeten we de sessiesleutel verkleinen. Voor het verkleinen kunnen we de normale ingebouwde python-functiereeks gebruiken [waarde: waarde]. Waarbij de waarde elke waarde kan zijn volgens de keuze van de gebruiker. In ons geval heb ik "key [: 16]" gedaan, waarbij 0 tot 16 waarden van de key nodig zijn. Deze conversie kan op veel manieren worden uitgevoerd, zoals sleutel [1:17] of sleutel [16:]. Het volgende deel is om een nieuwe IDEA-coderingsfunctie te maken door IDEA.new () te schrijven, waarvoor 3 argumenten nodig zijn voor verwerking. Het eerste argument is SLEUTEL, het tweede argument is de modus van de IDEA-codering (in ons geval IDEA.MODE_CTR) en het derde argument is de teller = wat een must-opvraagbare functie is. De teller = heeft een tekenreeksgrootte die wordt geretourneerd door de functie. Om de teller = te definiëren, moeten we redelijke waarden gebruiken. In dit geval heb ik de grootte van de KEY gebruikt door lambda te definiëren. In plaats van lambda te gebruiken, zouden we Counter.Util kunnen gebruiken die een willekeurige waarde genereert voor counter =. Om Counter.Util te gebruiken, moeten we de tellermodule van crypto importeren. Daarom is de code:

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

Nadat we "ideaEncrypt" eenmaal hadden gedefinieerd als onze IDEA-coderingsvariabele, kunnen we de ingebouwde coderingsfunctie gebruiken om elk bericht te coderen.

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

In dit codesegment is geheel het te coderen bericht en eMsg is het gecodeerde bericht. Na het coderen van het bericht, heb ik het omgezet in HEXADECIMAL om leesbaar te maken en upper () is de ingebouwde functie om de tekens in hoofdletters te plaatsen. Daarna wordt dit gecodeerde bericht naar het tegenovergestelde station verzonden voor decodering.

  • (Decryptie)

Om de gecodeerde berichten te decoderen, moeten we een andere coderingsvariabele maken met dezelfde argumenten en dezelfde sleutel, maar deze keer decodeert de variabele de gecodeerde berichten. De code hiervoor is hetzelfde als de vorige keer. Voordat we de berichten decoderen, moeten we het bericht echter decoderen vanuit hexadecimaal omdat we in ons coderingsgedeelte het gecodeerde bericht in hexadecimaal hebben gecodeerd om het leesbaar te maken. Daarom is de hele code:

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

Deze processen worden zowel op server- als op clientzijde uitgevoerd voor codering en decodering.

Server-side implementatie

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-side implementatie

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow