Алгоритм RSA на PYTHON

Алгоритм RSA на PYTHON

moderator E7

Всем привет ! Сегодня я расскажу и покажу очень популярный алгоритм ассиметричного шифрования- RSA.

Реализуем это на Python с использованием модулей.



Предисловие

Прежде чем начну, хочу сказать пару слов о видах шифрования.

  1. Симметричное
  2. Ассиметричное

таких картинок много , но что это всё означает ?

Симметричное - это такой тип шифрования, суть которого заключается в том, что при шифровании и дешифровании используется один и тот же ключ. Криптосистемы, они же так называемые шифры , имеют разную по своей сути шифрование данных, а если и шифрование разное , то и криптографические ключи тоже отличаются.

Вот парочка шифров:

  1. Шифр Цезаря - один из самых известных , в первую очередь из-за большого распространения в медиа-культуре. Ключом является число сдвига каждого символа шифруемых данных.
  2. Шифр Виженера - не менее популярный шифр, суть алгоритма проста - это последовательность шифров Цезаря с различными значениями сдвига.

Пишем алгоритм RSA

Мы узнали, что такое симметричное шифрование, пришло время перейти к алгоритму RSA, который в свою очередь относится к ассиметричному шифрованию. Пару слов о нём:

Асимметричное шифрование - это метод шифрования данных, предполагающий использование двух ключей - открытого и закрытого. Открытый (public) ключ применяется для шифрования информации, и может передаваться по незащищенным каналам. Закрытый (private) ключ применяется для расшифровки данных, зашифрованных открытым ключом. Открытый и закрытый ключи — это очень большие числа, связанные друг с другом определенной функцией, но так, что, зная одно, крайне сложно вычислить второе.


Параллельно с алгоритмом , мы напишем свой консольный чат с помощью модуля socket:

1 - Сервер



import socket

with socket.socket(socket.AF_INET , socket.SOCK_STREAM) as server:
    #bind the socket to address
    server.bind(("127.0.0.1", 1337))
    #listen channel 
    server.listen()
    #accepts client-socket
    client, client_addr = server.accept()
    while True:
        #input message and convert to bytes
        msg = input("server >> ").encode("utf-8")
        #send  to client.py
        client.sendall(msg)
        #received bytes and convert to string again
        data_received = client.recv(128)
        print("user :: " + data_received.decode("utf-8"))


На стороне сервера будет развёрнута криптосистема , но пока что сделаем клиента.

Стоит сразу упомянуть , чтобы вы акцентировали внимание на RSA , я не буду усложнять чат введением в него асинхронного кода.

А теперь давайте напишем клиента:

2 - Клиент



import socket
#create server-socket
with socket.socket(socket.AF_INET , socket.SOCK_STREAM) as server:
    #listen and connect to ip 127.0.0.1 and port 1337
    server.connect(("127.0.0.1" , 1337))

    while True:
       #received massive bytes from server
        data_received = server.recv(64)
        #output in terminal
        print("server :: "+ data_received.decode("utf-8"))
        #input and convert string to bytess
        msg = input("ME >> ").encode("utf-8")
        #send data to server 
        server.sendall(msg)



3 - RSA

На данном этапе я встрою в наш код RSA-алгоритм для передачи зашифрованной информации, в этом деле мне поможет модуль rsa.


first part

last part

import rsa

def generate_keys():
   (pubKey, privKey) = rsa.newkeys(1024)
   with open('keys/pubkey.pem', 'wb') as f:
       f.write(pubKey.save_pkcs1('PEM'))

   with open('keys/privkey.pem', 'wb') as f:
       f.write(privKey.save_pkcs1('PEM'))

def load_keys():
   with open('keys/pubkey.pem', 'rb') as f:
       pubKey = rsa.PublicKey.load_pkcs1(f.read())

   with open('keys/privkey.pem', 'rb') as f:
       privKey = rsa.PrivateKey.load_pkcs1(f.read())

   return pubKey, privKey

def encrypt(msg, key):
   return rsa.encrypt(msg.encode('ascii'), key)

def decrypt(ciphertext, key):
   try:
       return rsa.decrypt(ciphertext, key).decode('ascii')
   except:
       return False

def sign_sha1(msg, key):
   return rsa.sign(msg.encode('ascii'), key, 'SHA-1')

def verify_sha1(msg, signature, key):
   try:
       return rsa.verify(msg.encode('ascii'), signature, key) == 'SHA-1'
   except:
       return False

generate_keys()
pubKey, privKey = load_keys()

message = input('Enter a message:')
ciphertext = encrypt(message, pubKey)

signature = sign_sha1(message, privKey)

plaintext = decrypt(ciphertext, privKey)

print(f'Cipher text: {ciphertext}')
print(f'Signature: {signature}')

if plaintext:
   print(f'Plain text: {plaintext}')
else:
   print('Could not decrypt the message.')

if verify_sha1(plaintext, signature, pubKey):
   print('Signature verified!')
else:
   print('Could not verify the message signature.')


Сейчас я постараюсь объяснить как работает этот алгоритм.

Теперь представим следующую ситуацию. Есть Алиса, и есть Боб. Они сверхсекретные агенты, и они не могут выдать то, о чем они болтают между собой, и какие сверхсекретные данные передают. Алиса сидит на телефоне, Боб сидит на другом конце телефона а посередине сидит их общий заклятый враг и внимательно слушает, о чем они говорят. Алисе надо передать Бобу очень секретное число, но просто сказать по телефону она ему не может — враг не дремлет.


  • Алиса спрашивает у Боба открытый ключ, он ей говорит его по телефону. Ключ становится известен всем, в том числе не только Алисе, но и еще тому, кто сидит и слушает их
  • Алиса берет это число (открытый ключ), производит определенные действия над тем числом, что хочет закодировать и отсылает Бобу. Человек посередине эту информацию тоже перехватил.
  • Боб же берет закрытый ключ, который он создал вместе с открытым и производя математические действия, расшифровывает число Алисы
  • Человек посередине не знает закрытого ключа Боба, а по открытому ключу он не может ничего сделать, потому что расшифровать сообщение можно только с помощью закрытого. Человек с досады кусает свои локти.

Вкратце:


  • Боб создает открытый и закрытый ключи (они взаимосвязаны, как Том и Джерри)
  • Алиса получает открытый ключ Боба
  • Кодирует с его помощью свое число
  • Отсылает число по небезопасному каналу связи
  • Боб расшифровывает число с помощью закрытого ключа

Более абстрактно:


  • Создать открытый и закрытый ключи
  • Передать открытый ключ тому, кто будет шифровать
  • Зашифровать сообщение с помощью открытого ключа
  • Передать зашифрованное сообщение по каналу связи
  • Расшифровать сообщение с помощью закрытого ключа

Задача !

А теперь задача для читателя ! Вам будет необходимо дописать код чата, дополнив его алгоритмом RSA, написанным ранее.




С любовью от E7TEAM ;)

Report Page