Поиск…


Вступление

Криптография используется в целях безопасности. Существует не так много примеров шифрования / дешифрования в Python, использующих CREATE CREATE IDEA. Цель этой документации:

Расширение и внедрение схемы цифровой подписи RSA в связи между станциями. Использование Hash для целостности сообщения, то есть SHA-1. Создайте простой протокол передачи ключей. Шифровать ключ с помощью кода IDEA. Режим блочного шифрования - режим счетчика

замечания

Используемый язык: Python 2.7 (ссылка для загрузки: https://www.python.org/downloads/ )

Используемая библиотека:

* PyCrypto (ссылка для загрузки: https://pypi.python.org/pypi/pycrypto )

* PyCryptoPlus (ссылка для скачивания: https://github.com/doegox/python-cryptoplus )

Установка библиотеки:

PyCrypto: разархивируйте файл. Перейдите в каталог и откройте терминал для linux (alt + ctrl + t) и CMD (сдвиньте + правый щелчок + выберите командную строку, открытую здесь) для окон. После этого напишите python setup.py install (Make Sure Python Environment правильно настроена в ОС Windows)

PyCryptoPlus: такая же, как и последняя библиотека.

Выполнение задач: задача разделяется на две части. Один из них - процесс рукопожатия, а другой - процесс коммуникации. Настройка гнезда:

  • Как создание открытых и закрытых ключей, а также хэширование открытого ключа, нам нужно настроить сокет сейчас. Для настройки сокета нам нужно импортировать другой модуль со «импортным сокетом» и подключить (для клиента) или связать (для сервера) IP-адрес и порт с получением сокета от пользователя.

    ----------Сторона клиента----------

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

    ---------- Серверная сторона ---------

      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» позволит нам использовать функцию accept () и основные принципы обмена сообщениями. Вместо этого мы можем использовать «socket.AF_INET, socket.SOCK_DGRAM», но в то же время нам придется использовать setblocking (значение).

Процесс рукопожатия:

  • (КЛИЕНТ) Первой задачей является создание открытого и закрытого ключа. Чтобы создать закрытый и открытый ключ, нам нужно импортировать некоторые модули. Это: из Crypto import Random и из Crypto.PublicKey import RSA. Чтобы создать ключи, нам нужно написать несколько простых строк кодов:
random_generator = Random.new().read
        key = RSA.generate(1024,random_generator) 
        public = key.publickey().exportKey()

random_generator получен из модуля « из Crypto import Random ». Ключ получен из « из Crypto.PublicKey import RSA », который создаст закрытый ключ размером 1024, генерируя случайные символы. Публикация экспортирует открытый ключ из ранее сгенерированного закрытого ключа.

  • (CLIENT). После создания открытого и закрытого ключа мы должны использовать хэш для открытого ключа для отправки на сервер с использованием хэша SHA-1. Чтобы использовать хэш SHA-1, нам нужно импортировать другой модуль, написав «import hashlib». Для хэш-ключа мы пишем две строки кода:

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

Здесь hash_object и hex_digest - наша переменная. После этого клиент отправит hex_digest и public на сервер, и сервер проверит их, сравнив хэш с клиентом и новый хэш открытого ключа. Если новый хеш и хэш от клиента совпадают, он перейдет к следующей процедуре. Поскольку публикация, отправленная от клиента, имеет форму строки, она не сможет использоваться как ключ на стороне сервера. Чтобы предотвратить это и преобразовать открытый ключ строки в открытый ключ rsa, нам нужно написать server_public_key = RSA.importKey(getpbk) , здесь getpbk - это открытый ключ от клиента.

  • (SERVER) Следующий шаг - создать ключ сеанса. Здесь я использовал модуль «os» для создания случайного ключа «key = os.urandom (16)», который даст нам 16-битный длинный ключ, после чего я зашифровал этот ключ в «AES.MODE_CTR» и снова хешу с 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()
    

Таким образом, en_digest будет нашим ключом сеанса.

  • (SERVER) Для окончательной части процесса рукопожатия необходимо зашифровать открытый ключ, полученный от клиента, и ключ сеанса, созданный на стороне сервера.

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

После шифрования сервер отправит ключ клиенту в виде строки.

  • (CLIENT) После получения зашифрованной строки (открытого и сеансового ключа) с сервера клиент расшифрует их с помощью Private Key, который был создан ранее вместе с открытым ключом. Поскольку зашифрованный (открытый и сеансовый ключ) был в форме строки, теперь мы должны вернуть его в качестве ключа, используя eval (). Если дешифрование завершено, процесс рукопожатия завершается также, когда обе стороны подтверждают, что используют одни и те же ключи. Чтобы расшифровать:

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

Я использовал SHA-1 здесь, чтобы он был доступен для чтения на выходе.

Процесс коммуникации:

Для коммуникационного процесса мы должны использовать ключ сеанса с обеих сторон в качестве ключа для кодирования IDEA MODE_CTR. Обе стороны будут шифровать и дешифровать сообщения с помощью IDEA.MODE_CTR, используя ключ сеанса.

  • (Шифрование) Для шифрования IDEA нам нужен ключ размером 16 бит и счетчик, который должен быть вызван. Счетчик является обязательным в MODE_CTR. Ключ сеанса, который мы зашифровали и хешировал, теперь имеет размер 40, который будет превышать предельный ключ шифрования IDEA. Следовательно, нам нужно уменьшить размер ключа сеанса. Для сокращения мы можем использовать обычный питон, встроенный в строку функций [значение: значение]. Если значение может быть любым значением в соответствии с выбором пользователя. В нашем случае я сделал «key [: 16]», где от ключа будет от 0 до 16 значений. Это преобразование можно было бы сделать многими способами, такими как клавиша [1:17] или клавиша [16:]. Следующая часть - создать новую функцию шифрования IDEA, написав IDEA.new (), которая будет принимать 3 аргумента для обработки. Первым аргументом будет KEY, вторым аргументом будет режим шифрования IDEA (в нашем случае IDEA.MODE_CTR), а третьим аргументом будет счетчик = который является обязательной вызываемой функцией. Счетчик = будет содержать размер строки, который будет возвращен функцией. Чтобы определить счетчик =, мы должны использовать разумные значения. В этом случае я использовал размер KEY, определяя лямбда. Вместо использования лямбда мы могли бы использовать Counter.Util, который генерирует случайное значение для counter =. Чтобы использовать Counter.Util, нам нужно импортировать модуль счетчика из crypto. Следовательно, код будет:

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

Определив «ideaEncrypt» как нашу переменную шифрования IDEA, мы можем использовать встроенную функцию шифрования для шифрования любого сообщения.

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

В этом сегменте кода целое является зашифрованным сообщением, а eMsg является зашифрованным сообщением. После шифрования сообщения я преобразовал его в HEXADECIMAL, чтобы сделать readable и upper () - встроенной функцией, чтобы сделать символы в верхнем регистре. После этого это зашифрованное сообщение будет отправлено на противоположную станцию ​​для дешифрования.

  • (Дешифрование)

Чтобы расшифровать зашифрованные сообщения, нам нужно будет создать другую переменную шифрования, используя те же аргументы и тот же ключ, но на этот раз переменная расшифрует зашифрованные сообщения. Код для этого же, как и в последний раз. Однако перед расшифровкой сообщений нам нужно декодировать сообщение из шестнадцатеричного числа, поскольку в нашей части шифрования мы закодировали зашифрованное сообщение в шестнадцатеричном виде, чтобы сделать чтение. Следовательно, весь код будет:

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

Эти процессы будут выполняться как на стороне сервера, так и на стороне клиента для шифрования и дешифрования.

Реализация на стороне сервера

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

Реализация клиентской стороны

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow