diff --git a/lab_3/asym_RSA.py b/lab_3/asym_RSA.py new file mode 100644 index 00000000..c4a3bc51 --- /dev/null +++ b/lab_3/asym_RSA.py @@ -0,0 +1,28 @@ +from cryptography.hazmat.primitives.asymmetric import padding +from cryptography.hazmat.primitives import hashes + +class AsymRSA: + """ + Класс асимметричного шифрования и дешифрования через RSA + """ + @staticmethod + def encrypt_rsa(text: bytes, public_key): + """ + Ассиметричное шифрование текста по публичному ключу + :param text: Текст для зашифровки + :param public_key: Публичный ключ для шифрования + """ + return public_key.encrypt(text, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()),algorithm=hashes.SHA256(),label=None)) + + + @staticmethod + def decrypt_rsa(encrypted_text: bytes, private_key) -> bytes: + """ + Ассиметричное дешифрование текста по приватному ключу + :param encrypted_text: Зашифрованный текст + :param private_key: Приватный ключ для дешифрования + """ + return private_key.decrypt(encrypted_text, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), label=None)) + + diff --git a/lab_3/config.py b/lab_3/config.py new file mode 100644 index 00000000..213bac9a --- /dev/null +++ b/lab_3/config.py @@ -0,0 +1,19 @@ +import json + +try: + with open("settings.json", 'r', encoding='utf-8') as js: + config = json.load(js) + + INITIAL_FILE = config["initial_file"] + ENCRYPTED_FILE = config["encrypted_file"] + DECRYPTED_FILE = config["decrypted_file"] + SYMMETRIC_KEY = config["symmetric_key"] + PUBLIC_KEY = config["public_key"] + PRIVATE_KEY = config["secret_key"] + NONCE_FILE = config["nonce_file"] + +except FileNotFoundError: + print("Файл settings.json не найден.") + +except Exception as e: + print(f"Ошибка при загрузке конфигурационных данных: {e}") \ No newline at end of file diff --git a/lab_3/decrypted_text.txt b/lab_3/decrypted_text.txt new file mode 100644 index 00000000..d80b44f7 --- /dev/null +++ b/lab_3/decrypted_text.txt @@ -0,0 +1,2 @@ +В современном мире программирование стало фундаментальным навыком, сравнимым с чтением и письмом. Умение понимать язык компьютеров открывает невероятные возможности — от создания сайтов до разработки искусственного интеллекта. Каждая строка кода превращает абстрактную идею в работающее приложение или полезный сервис. +Изучение программирования развивает логическое мышление, учит решать сложные задачи путем их разбиения на более простые части. Этот навык полезен не только разработчикам, но и ученым, аналитикам, дизайнерам. В эпоху цифровизации понимание принципов работы ПО становится конкурентным преимуществом на рынке труда. \ No newline at end of file diff --git a/lab_3/encripted_text.bin b/lab_3/encripted_text.bin new file mode 100644 index 00000000..e69de29b diff --git a/lab_3/encrypted_text.bin b/lab_3/encrypted_text.bin new file mode 100644 index 00000000..15309c88 Binary files /dev/null and b/lab_3/encrypted_text.bin differ diff --git a/lab_3/file_manager.py b/lab_3/file_manager.py new file mode 100644 index 00000000..12540ed5 --- /dev/null +++ b/lab_3/file_manager.py @@ -0,0 +1,45 @@ +import json + +class FileManager: + _path_file: str = "" + _method: str = "" + + def __init__(self, path_file="", method=""): + self._path_file = path_file + self._method = method + + def read(self, path_file="", method=""): + try: + if path_file != "": + self._path_file = path_file + else: self._path_file = self._path_file + + if method != "": + self._method = method + else: self._method = self._method + + if self._method != "r": + with open(self._path_file, self._method) as f: + return f.read() + else: + with open(self._path_file, self._method, encoding='utf-8') as f: + return f.read() + + except Exception as ex: + raise Exception(f"Ошибка чтения: {ex}") + + def write(self, data, path_file="", method=""): + try: + if path_file != "": + self._path_file = path_file + else: self._path_file = self._path_file + + if method != "": + self._method = method + else: self._method = self._method + + with open(self._path_file, self._method) as f: + f.write(data) + + except Exception as ex: + raise Exception(f"Ошибка записи: {ex}") \ No newline at end of file diff --git a/lab_3/generate_keys.py b/lab_3/generate_keys.py new file mode 100644 index 00000000..7971deac --- /dev/null +++ b/lab_3/generate_keys.py @@ -0,0 +1,35 @@ +import os +from cryptography.hazmat.primitives.asymmetric import rsa + + +class GenerateKey: + """ + Класс для генерации ключей + """ + + @staticmethod + def generate_sym_key() -> tuple: + """ + Создает симметричный ключ (256 бит) и одноразовое случайное число (128 бит) + :return: Кортеж из симметричного ключ и одноразового случайного числа + """ + key_size = 32 # 256 бит = 32 байта + nonce_size = 16 # 128 бит = 16 байтов + + key = os.urandom(key_size) + nonce = os.urandom(nonce_size) + + return key, nonce + + @staticmethod + def generate_asym_keys() -> tuple: + """ + Создает пару асимметричных ключей RSA + :return: Кортеж из приватного и публичного ключей + """ + key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048 + ) + return key, key.public_key() + diff --git a/lab_3/main.py b/lab_3/main.py new file mode 100644 index 00000000..c07067b2 --- /dev/null +++ b/lab_3/main.py @@ -0,0 +1,30 @@ +import os +import argparse +from scenaries import Scenario + + +def main(): + parser = argparse.ArgumentParser() + group = parser.add_mutually_exclusive_group(required = True) + group.add_argument('-gen', '--generation', help='Запускает режим генерации ключей', action='store_true') + group.add_argument('-enc', '--encryption', help='Запускает режим шифрования', action='store_true') + group.add_argument('-dec', '--decryption', help='Запускает режим дешифрования', action='store_true') + + args = parser.parse_args() + + try: + if args.generation: + Scenario.generate_keys() + elif args.encryption: + Scenario.encrypt_text() + elif args.decryption: + Scenario.decrypt_text() + else: + print("Ошибка: Выбран не существующий вариант") + + except Exception as e: + print(f"Произошла критическая ошибка: {e}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/lab_3/nonce.bin b/lab_3/nonce.bin new file mode 100644 index 00000000..22da50b2 --- /dev/null +++ b/lab_3/nonce.bin @@ -0,0 +1 @@ +FsPޒ. \ No newline at end of file diff --git a/lab_3/private_key.pem b/lab_3/private_key.pem new file mode 100644 index 00000000..19dc7f29 --- /dev/null +++ b/lab_3/private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAtU3ADpdTZ1jmGtfEFyPAq6I2kgaWumRworK4ogiMKhsFaCzy +DDkIIDXB2bhR+rwS7Z0Zfrs22HhD68sBklag9RGT4jorgC/HR9zAjA76fghzMdAF +gR5y03rh8A49r9eTOlbc4QZsh/tXBHWzhLuCLf/UUxPtFz9TUBEKDOLPqhL7xdcu +LyiZK4153C8e6Qu3HsuXsSbvIRgvu4MHmGZheAV1H9DPFxJWdHCcOKSdcl/Y0D/D +Trj/ID0Rdsux3gRcxjbW550jUOljcPntyccWURg2ybnHQT48U3ThmcNJbol9HpTs +FnGqXWWko1UeJAMiZT2C5XQUMflFRy2nr33/ZQIDAQABAoIBAA3jjWVwwUJnBIWk +5tAw/HcJf62zFIPl4t0L3OoIxpgJJuJiow49pjo1dAq2PI19L+QFB2l2dQ6jM+zR +yeaIfV8YwB/x/dgdkOIX7qYsFZNnGVAFFA7eosRBoyJNLPuWA6DR+6y/XbwTDIj6 +bUyrQp88fGr62UxRHRRCoeb3zxnDpmfriOm25EF9muPP1GncRSP2FZxkb761onXT +7hG2jIpKywdkipFafkB4ynay3daCvXsF0WVC2fl4Bj+P8nVgFJF8EXz0emr2ns3q +02Uimr0tw8xeYXP2n6IeRC/G9xL+7pAsk4Ga6AhRKJ2Qwn7HetC0m/UTHT+GjQqL +Q86jITcCgYEA6gcyETqAIb7nmvZ0XMQ2gCR6BRN0y+fmjQ0vyxj4Ljh7yEHcOJTc +l/7NUlZynpyXhmIvfwklKXuD5Mu1tY6uqnXoC15vRSKMDX++sW2krd0KEnW/wMKv +sk1+WDi9VZm/fN3lC0OmV8MYqlEng/qfREfriNNqonBsFTUiksR+TL8CgYEAxlNW +asfY1Tptz++PQGnJ65Nu1nxyhPcxOAkLKncWYYFMkl4kn5cje939FkF7AzoAT3wL +mu1GKdAq7JgBW9MyAXlMK6CI5Kjx4lgMSF7JNK7fgwlxvFYD3Ud3THfVfj+DRgdD +nYGR82qw31xh93+kfmur8SnE/4D0zEbAl28rqNsCgYA/uvvocyzng6xgp9LiXFCX +LtfHwBejW6COMtQcE82qEJms3DqTcf5sqefSD1ahWPVulBhpGN104Xz2dn8iVRu9 +seQiDHJyuki3eF0+xiP9cN9ITaaNYLcl8DKC5dixke/ymh7ApYiMB8YUw4rmRv7O +QmOi3CgC2mikkda7byUR0wKBgQC5vV8XzmcS/A/QSGn/R5RmXsPVeOPAB8o+0ql0 +ceeyFehixGzEUkZXQcY/y7+re+zChEhSJpopmt44ivvqxdb1bmaaDVVn4Zn4A8It +HSiPgJ+wF24/lsczvDTMlwaJoG4Pbcozfx/zux4/ckQGCbNC+xAjYp0vNdUOY80H +hoR7NQKBgCrJyRevJf0pLCi9d+nSBviFM5x8DyMvQUp0MZH7otfG1t6wDSpnIgtY +0vNpN8VpGmLiQFDxd5dXn+3h+a+ged/T+NCRaRDBNIH289ciyuLiWpR4l1T4N3ut +qK6DUZN8inOajvOZ73j9zPFnXw3L26UBFuIzoJsHsPo9u+DLck+I +-----END RSA PRIVATE KEY----- diff --git a/lab_3/public_key.pem b/lab_3/public_key.pem new file mode 100644 index 00000000..a3b47f65 --- /dev/null +++ b/lab_3/public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtU3ADpdTZ1jmGtfEFyPA +q6I2kgaWumRworK4ogiMKhsFaCzyDDkIIDXB2bhR+rwS7Z0Zfrs22HhD68sBklag +9RGT4jorgC/HR9zAjA76fghzMdAFgR5y03rh8A49r9eTOlbc4QZsh/tXBHWzhLuC +Lf/UUxPtFz9TUBEKDOLPqhL7xdcuLyiZK4153C8e6Qu3HsuXsSbvIRgvu4MHmGZh +eAV1H9DPFxJWdHCcOKSdcl/Y0D/DTrj/ID0Rdsux3gRcxjbW550jUOljcPntyccW +URg2ybnHQT48U3ThmcNJbol9HpTsFnGqXWWko1UeJAMiZT2C5XQUMflFRy2nr33/ +ZQIDAQAB +-----END PUBLIC KEY----- diff --git a/lab_3/scenaries.py b/lab_3/scenaries.py new file mode 100644 index 00000000..6674ad93 --- /dev/null +++ b/lab_3/scenaries.py @@ -0,0 +1,86 @@ +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.serialization import load_pem_public_key, load_pem_private_key +from config import ( + DECRYPTED_FILE, + ENCRYPTED_FILE, + INITIAL_FILE, + PRIVATE_KEY, + SYMMETRIC_KEY, + PUBLIC_KEY, + NONCE_FILE +) +from asym_RSA import AsymRSA +from sym_ChaCha20 import ChaCha20 +from generate_keys import GenerateKey +from file_manager import FileManager + + +class Scenario: + + @staticmethod + def generate_keys(): + """ + Сценарий генерации ключей. + Генерирует публичный и приватный ассиметричные ключи, + так же генерирует симметричный ключ и ассиметрично шифрует его. + Все ключи записываются в соответствующие файлы + """ + file_manager = FileManager() + + private_key, public_key = GenerateKey.generate_asym_keys() + sym_key, nonce = GenerateKey.generate_sym_key() + + file_manager.write(public_key.public_bytes(encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo),PUBLIC_KEY, "wb") + file_manager.write(private_key.private_bytes(encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption()), PRIVATE_KEY, "wb") + + encrypt_sym_key = AsymRSA.encrypt_rsa(sym_key, public_key) + file_manager.write(nonce, NONCE_FILE, "wb") + file_manager.write(encrypt_sym_key, SYMMETRIC_KEY, "wb") + + print(f"Успешно завершен сценарий генерации ключей, сохранено в файлах: {PUBLIC_KEY}, {PRIVATE_KEY}, {SYMMETRIC_KEY}\n") + + + @staticmethod + def encrypt_text(): + """ + Сценарий шифрования текста. + Использует заранее сгенерированные ключи и шифрует текст симметричным способом + """ + file_manager = FileManager() + + private_bytes = file_manager.read(PRIVATE_KEY, "rb") + private_key = load_pem_private_key(private_bytes, password=None) + + encrypted_sym_key = file_manager.read(SYMMETRIC_KEY, "rb") + sym_key = AsymRSA.decrypt_rsa(encrypted_sym_key, private_key) + nonce = file_manager.read(NONCE_FILE, "rb") + + text = file_manager.read(INITIAL_FILE, "r") + encrypted_text = ChaCha20.encrypt_chacha20(text, sym_key, nonce) + file_manager.write(encrypted_text, ENCRYPTED_FILE, "wb") + + print(f"Успешно завершен сценарий шифрования текста, записан в файле: {ENCRYPTED_FILE}\n") + + + @staticmethod + def decrypt_text(): + """ + Сценарий дешифрования текста. + Использует заранее сгенерированные ключи и дешифрует текст симметричным способом + """ + file_manager = FileManager() + + private_bytes = file_manager.read(PRIVATE_KEY, "rb") + private_key = load_pem_private_key(private_bytes, password=None) + encrypted_sym_key = file_manager.read(SYMMETRIC_KEY, "rb") + sym_key = AsymRSA.decrypt_rsa(encrypted_sym_key, private_key) + nonce = file_manager.read(NONCE_FILE, "rb") + + data = file_manager.read(ENCRYPTED_FILE, "rb") + decrypted_text = ChaCha20.decrypt_chacha20(data, sym_key, nonce) + file_manager.write(decrypted_text, DECRYPTED_FILE, "wb") + + print(f"Успешно завершен сценарий дешифрования текста, записан в файле: {DECRYPTED_FILE}\n") \ No newline at end of file diff --git a/lab_3/settings.json b/lab_3/settings.json new file mode 100644 index 00000000..36f98687 --- /dev/null +++ b/lab_3/settings.json @@ -0,0 +1,9 @@ +{ + "initial_file": "text.txt", + "encrypted_file": "encrypted_text.bin", + "decrypted_file": "decrypted_text.txt", + "symmetric_key": "sym_key.bin", + "public_key": "public_key.pem", + "secret_key": "private_key.pem", + "nonce_file": "nonce.bin" +} \ No newline at end of file diff --git a/lab_3/sym_ChaCha20.py b/lab_3/sym_ChaCha20.py new file mode 100644 index 00000000..73b8934c --- /dev/null +++ b/lab_3/sym_ChaCha20.py @@ -0,0 +1,36 @@ +import os +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms + + +class ChaCha20: + """ + Класс для симметричного шифрования и дешифрования через ChaCha20 + """ + @staticmethod + def encrypt_chacha20(text: str, key: bytes, nonce: bytes) -> bytes: + """ + Шифрование текста по ChaCha20 симметричным ключом + :param text: Текст для зашифровки + :param key: Ключ шифрования + :param nonce: Одноразовое число для шифрования + """ + cipher = Cipher(algorithms.ChaCha20(key, nonce), mode=None) + encryptor = cipher.encryptor() + + return encryptor.update(text.encode('utf-8')) + + + @staticmethod + def decrypt_chacha20(encrypt_text: bytes, key: bytes, nonce: bytes) -> bytes: + """ + Дешифрование текста по ChaCha20 симметричным ключом + :param encrypt_text: Зашифрованный текст + :param key: Ключ для дешифрования + :param nonce: Одноразовое число использовавшееся при шифровании + """ + cipher = Cipher(algorithms.ChaCha20(key, nonce), mode=None) + decryptor = cipher.decryptor() + + return decryptor.update(encrypt_text) + + diff --git a/lab_3/sym_key.bin b/lab_3/sym_key.bin new file mode 100644 index 00000000..d0cf521c --- /dev/null +++ b/lab_3/sym_key.bin @@ -0,0 +1 @@ +"۲5,ޡh(-?}WۼO]߆"=r-q\ivb L|'x$W=mS0?>#=7c>UFi-+͢ǎ%"02F:K`9 eUqS>C+&p/[~rX0 sUf!dYe~0 #؜fkB ox#S?,]O;G2Zn@ivD ݡo7!C঴7kp N= \ No newline at end of file diff --git a/lab_3/text.txt b/lab_3/text.txt new file mode 100644 index 00000000..d80b44f7 --- /dev/null +++ b/lab_3/text.txt @@ -0,0 +1,2 @@ +В современном мире программирование стало фундаментальным навыком, сравнимым с чтением и письмом. Умение понимать язык компьютеров открывает невероятные возможности — от создания сайтов до разработки искусственного интеллекта. Каждая строка кода превращает абстрактную идею в работающее приложение или полезный сервис. +Изучение программирования развивает логическое мышление, учит решать сложные задачи путем их разбиения на более простые части. Этот навык полезен не только разработчикам, но и ученым, аналитикам, дизайнерам. В эпоху цифровизации понимание принципов работы ПО становится конкурентным преимуществом на рынке труда. \ No newline at end of file