From 793b078f2f4094bb50cdbba9de10f9e48f11ce7a Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:11:52 +0400 Subject: [PATCH 01/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=81=D0=B8=D0=BC=D0=BC=D0=B5=D1=82=D1=80=D0=B8?= =?UTF-8?q?=D1=87=D0=BD=D1=8B=D0=B9=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8?= =?UTF-8?q?=D1=82=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- symmetric_alg.py | 108 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 symmetric_alg.py diff --git a/symmetric_alg.py b/symmetric_alg.py new file mode 100644 index 000000000..30d82d156 --- /dev/null +++ b/symmetric_alg.py @@ -0,0 +1,108 @@ +from cryptography.hazmat.primitives import padding as symmetric_padding +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +import os + + +class SymCipherManager: + """Класс для симметричного шифрования с использованием алгоритма SM4""" + + @staticmethod + def generate_sm4_key() -> bytes: + """ + Генерирует ключ алгоритма шифрования SM4 + :return: 16-байтный ключ + :raises RuntimeError: Если не удалось сгенерировать ключ + """ + try: + return os.urandom(16) + except Exception as e: + raise RuntimeError("Ошибка генерации ключа") from e + + @staticmethod + def apply_padding(data: bytes) -> bytes: + """ + Добавляет PKCS7 паддинг к данным + :param data: Данные для паддинга + :return: Данные с паддингом + :raises TypeError: Если данные не в формате bytes + """ + if not isinstance(data, bytes): + raise TypeError("Данные должны быть в формате bytes") + + padder = symmetric_padding.PKCS7(128).padder() + return padder.update(data) + padder.finalize() + + @staticmethod + def remove_padding(data: bytes) -> bytes: + """ + Удаляет PKCS7 паддинг из данных + :param data: данные с паддингом + :return: данные без паддинга + :raises TypeError: Если данные не в формате bytes + """ + if not isinstance(data, bytes): + raise TypeError("Данные должны быть в формате bytes") + + unpadder = symmetric_padding.PKCS7(128).unpadder() + try: + return unpadder.update(data) + unpadder.finalize() + except Exception as e: + raise RuntimeError("Ошибка удаления паддинга") from e + + @staticmethod + def encrypt_sm4(text: bytes, key: bytes) -> bytes: + """ + Шифрует текст с помощью алгоритма SM4 + :param text: Текст для шифрования + :param key: Ключ шифрования (16 байт) + :return: iv + зашифрованный текст + :raises TypeError: Если неверный тип данных + :raises ValueError: Если неверная длина ключа или данных + :raises RuntimeError: Если ошибка шифрования + """ + if not isinstance(text, bytes) or not isinstance(key, bytes): + raise TypeError("Данные и ключ должны быть в формате bytes") + if len(key) != 16: + raise ValueError("Ключ должен быть длиной 16 байт") + if not text: + raise ValueError("Текст для шифрования не может быть пустым") + + try: + iv = os.urandom(16) + padded_data = SymCipherManager.apply_padding(text) + cipher = Cipher(algorithms.SM4(key), modes.CBC(iv)) + encryptor = cipher.encryptor() + ciphertext = encryptor.update(padded_data) + encryptor.finalize() + + return iv + ciphertext + except Exception as e: + raise RuntimeError("Ошибка шифрования") from e + + @staticmethod + def decrypt_sm4(ciphertext: bytes, key: bytes) -> bytes: + """ + Расшифровывает текст с помощью алгоритма SM4 + :param ciphertext: iv + зашифрованный текст + :param key: Ключ расшифровки + :return: Расшифрованный текст + :raises TypeError: Если неверный тип данных + :raises ValueError: Если неверная длина ключа или данных + :raises RuntimeError: Если ошибка дешифрования + """ + if not isinstance(ciphertext, bytes) or not isinstance(key, bytes): + raise TypeError("Данные и ключ должны быть в формате bytes") + if len(key) != 16: + raise ValueError("Ключ должен быть 16 байт") + if len(ciphertext) < 16: + raise ValueError("Шифротекст короткий") + + try: + iv = ciphertext[:16] + encrypted_data = ciphertext[16:] + cipher = Cipher(algorithms.SM4(key), modes.CBC(iv)) + decryptor = cipher.decryptor() + padded_text = decryptor.update(encrypted_data) + decryptor.finalize() + + return SymCipherManager.remove_padding(padded_text) + except Exception as e: + raise RuntimeError("Ошибка дешифрования") from e \ No newline at end of file From 3132cc03df3db448a281913cae72fddae9b4f7f7 Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:19:03 +0400 Subject: [PATCH 02/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D0=B0=D1=81=D1=81=D0=B8=D0=BC=D0=B5=D1=82=D1=80?= =?UTF-8?q?=D0=B8=D1=87=D0=BD=D1=8B=D0=B9=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80?= =?UTF-8?q?=D0=B8=D1=82=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asymmetric_alg.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 asymmetric_alg.py diff --git a/asymmetric_alg.py b/asymmetric_alg.py new file mode 100644 index 000000000..fe7890aa7 --- /dev/null +++ b/asymmetric_alg.py @@ -0,0 +1,77 @@ +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding, rsa +from cryptography.hazmat.backends import default_backend + + +class AsymCipherManager: + """Класс для асимметричного шифрования с использованием RSA""" + + @staticmethod + def generate_rsa_keys() -> tuple[rsa.RSAPrivateKey, rsa.RSAPublicKey]: + """ + Генерирует пару закрытый RSA ключ и открытый RSA ключ + :return: Кортеж (закрытый ключ, открытый ключ) + :raises RuntimeError: Если не удалось сгенерировать ключи + """ + try: + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + backend=default_backend() + ) + public_key = private_key.public_key() + return private_key, public_key + except Exception as e: + raise RuntimeError("Ошибка генерации RSA ключей") from e + + @staticmethod + def encrypt_key(sym_key: bytes, public_key: rsa.RSAPublicKey) -> bytes: + """ + Шифрует симметричный ключ с помощью открытого + :param sym_key: Симметричный ключ для шифрования + :param public_key: Открытый RSA ключ + :return: Зашифрованный симметричный ключ + :raises TypeError: Если неверный тип аргументов + :raises ValueError: Если ключ пустой или слишком большой + :raises RuntimeError: Если ошибка шифрования + """ + if not isinstance(sym_key, bytes): + raise TypeError("Симметричный ключ должен быть в формате bytes") + if not isinstance(public_key, rsa.RSAPublicKey): + raise TypeError("Открытый ключ должен быть типа RSAPublicKey") + if not sym_key: + raise ValueError("Симметричный ключ не может быть пустым") + + try: + return public_key.encrypt( + sym_key, + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), + label=None + ) + ) + except Exception as e: + raise RuntimeError("Ошибка шифрования ключа") from e + + @staticmethod + def decrypt_key(encr_key: bytes, private_key: rsa.RSAPrivateKey) -> bytes: + + if not isinstance(encr_key, bytes): + raise TypeError("Зашифрованный ключ должен быть в формате bytes") + if not isinstance(private_key, rsa.RSAPrivateKey): + raise TypeError("Закрытый ключ должен быть типа RSAPrivateKey") + if not encr_key: + raise ValueError("Зашифрованный ключ не может быть пустым") + + try: + return private_key.decrypt( + encr_key, + padding.OAEP( + mgf=padding.MGF1(algorithm=hashes.SHA256()), + algorithm=hashes.SHA256(), + label=None + ) + ) + except Exception as e: + raise RuntimeError("Ошибка дешифрования ключа") from e \ No newline at end of file From 427aa38bfd19eb5f59b7301e24d8539c601ccf30 Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:21:52 +0400 Subject: [PATCH 03/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D0=B4=D0=BE=D0=BA=D1=81=D1=82=D1=80=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asymmetric_alg.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/asymmetric_alg.py b/asymmetric_alg.py index fe7890aa7..23317bd5d 100644 --- a/asymmetric_alg.py +++ b/asymmetric_alg.py @@ -56,7 +56,15 @@ def encrypt_key(sym_key: bytes, public_key: rsa.RSAPublicKey) -> bytes: @staticmethod def decrypt_key(encr_key: bytes, private_key: rsa.RSAPrivateKey) -> bytes: - + """ + Расшифровывает симметричный ключ с помощью закрытого + :param encr_key: Зашифрованный симметричный ключ + :param private_key: Закрытый RSA ключ + :return: Расшифрованный симметричный ключ + :raises TypeError: Если неверный тип аргументов + :raises ValueError: Если зашифрованный ключ пустой + :raises RuntimeError: Если ошибка дешифрования + """ if not isinstance(encr_key, bytes): raise TypeError("Зашифрованный ключ должен быть в формате bytes") if not isinstance(private_key, rsa.RSAPrivateKey): From 843a9297549708adb31a43eed1a10e4e44219a96 Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:24:44 +0400 Subject: [PATCH 04/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=81=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8E=20=D0=B8=20=D0=B4=D0=B5=D1=81=D0=B5?= =?UTF-8?q?=D1=80=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- serialize.py | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 serialize.py diff --git a/serialize.py b/serialize.py new file mode 100644 index 000000000..cbd898901 --- /dev/null +++ b/serialize.py @@ -0,0 +1,128 @@ +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.serialization import ( + load_pem_public_key, + load_pem_private_key, +) + + +def serialize_public_key(path: str, public_key: rsa.RSAPublicKey) -> None: + """ + Сериализует открытый RSA-ключ в файл. + :param path: Путь к файлу для сохранения + :param public_key: Открытый RSA-ключ + :raises ValueError: Если ключ недействителен + :raises IOError: Если произошла ошибка записи + """ + if not isinstance(public_key, rsa.RSAPublicKey): + raise ValueError("Неверный тип открытого ключа") + + try: + pem = public_key.public_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + with open(path, 'wb') as f: + f.write(pem) + except IOError as e: + raise IOError(f"Ошибка записи открытого ключа: {e}") + except Exception as e: + raise ValueError(f"Ошибка сериализации открытого ключа: {e}") + + +def serialize_private_key(path: str, private_key: rsa.RSAPrivateKey) -> None: + """ + Сериализует закрытый RSA-ключ в файл. + :param path: Путь к файлу для сохранения + :param private_key: Закрытый RSA-ключ + :raises ValueError: Если ключ недействителен + :raises IOError: Если произошла ошибка записи + """ + if not isinstance(private_key, rsa.RSAPrivateKey): + raise ValueError("Неверный тип закрытого ключа") + + try: + pem = private_key.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption() + ) + with open(path, 'wb') as f: + f.write(pem) + except IOError as e: + raise IOError(f"Ошибка записи закрытого ключа: {e}") + except Exception as e: + raise ValueError(f"Ошибка сериализации закрытого ключа: {e}") + + +def serialize_sym_key(path: str, sym_key: bytes) -> None: + """ + Сериализует симметричный ключ в файл. + :param path: Путь к файлу для сохранения + :param sym_key: Симметричный ключ + :raises ValueError: Если ключ пустой + :raises IOError: Если произошла ошибка записи + """ + if not sym_key: + raise ValueError("Симметричный ключ не может быть пустым") + + try: + with open(path, 'wb') as f: + f.write(sym_key) + except IOError as e: + raise IOError(f"Ошибка записи симметричного ключа: {e}") + + +def deserialize_public_key(path: str) -> rsa.RSAPublicKey: + """ + Десериализует открытый RSA-ключ из файла. + :param path: Путь к файлу с ключом + :return: Открытый RSA-ключ + :raises IOError: Если произошла ошибка чтения + :raises ValueError: Если файл поврежден + """ + try: + with open(path, 'rb') as f: + pem = f.read() + return load_pem_public_key(pem, backend=default_backend()) + except IOError as e: + raise IOError(f"Ошибка чтения открытого ключа: {e}") + except Exception as e: + raise ValueError(f"Ошибка десериализации открытого ключа: {e}") + + +def deserialize_private_key(path: str) -> rsa.RSAPrivateKey: + """ + Десериализует закрытый RSA-ключ из файла. + :param path: Путь к файлу с ключом + :return: Закрытый RSA-ключ + :raises IOError: Если произошла ошибка чтения + :raises ValueError: Если файл поврежден + """ + try: + with open(path, 'rb') as f: + pem = f.read() + return load_pem_private_key(pem, password=None, backend=default_backend()) + except IOError as e: + raise IOError(f"Ошибка чтения закрытого ключа: {e}") + except Exception as e: + raise ValueError(f"Ошибка десериализации закрытого ключа: {e}") + + +def deserialize_sym_key(path: str) -> bytes: + """ + Десериализует симметричный ключ из файла. + :param path: Путь к файлу с ключом + :return: Симметричный ключ + :raises IOError: Если произошла ошибка чтения + :raises ValueError: Если файл пустой + """ + try: + with open(path, 'rb') as f: + key = f.read() + if not key: + raise ValueError("Файл с симметричным ключом пуст") + return key + except IOError as e: + raise IOError(f"Ошибка чтения симметричного ключа: {e}") \ No newline at end of file From 0e1e5bccd1f9e1115a1fcc44b9b79aed380714cf Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:26:58 +0400 Subject: [PATCH 05/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?= =?UTF-8?q?=D1=81=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- file_work.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 file_work.py diff --git a/file_work.py b/file_work.py new file mode 100644 index 000000000..a3821c0ca --- /dev/null +++ b/file_work.py @@ -0,0 +1,78 @@ +import json + +def read_json_file(file_path: str) -> dict: + """ + Читает данные из JSON файла + :param file_path: Путь к JSON файлу + :return: Словарь с данными из файла + :raises FileNotFoundError: Если файл не существует + :raises PermissionError: Если нет прав на чтение файла + :raises Exception: При других ошибках чтения + """ + try: + with open(file_path, 'r', encoding='utf-8') as file: + return json.load(file) + except FileNotFoundError as e: + raise FileNotFoundError(f"Файл не найден: {file_path}") from e + except PermissionError as e: + raise PermissionError(f"Нет прав на чтение файла: {file_path}") from e + except Exception as e: + raise Exception(f"Ошибка при чтении JSON файла: {file_path}") from e + +def write_json_file(file_path: str, data: dict) -> None: + """ + Записывает данные в JSON файл + :param file_path: Путь к файлу для записи + :param data: Данные для записи (словарь) + :raises TypeError: Если данные не сериализуемы в JSON + :raises PermissionError: Если нет прав на запись + :raises Exception: При других ошибках записи + """ + try: + with open(file_path, 'w', encoding='utf-8') as file: + json.dump(data, file, ensure_ascii=False, indent=4) + except TypeError as e: + raise TypeError(f"Ошибка сериализации данных в JSON: {e}") from e + except PermissionError as e: + raise PermissionError(f"Нет прав на запись в файл: {file_path}") from e + except Exception as e: + raise Exception(f"Ошибка при записи JSON файла: {file_path}") from e + +def read_bin_file(file_path: str) -> bytes: + """ + Читает содержимое бинарного файла + :param file_path: Путь к бинарному файлу + :return: Байтовая строка с содержимым файла + :raises FileNotFoundError: Если файл не существует + :raises PermissionError: Если нет прав на чтение + :raises Exception: При других ошибках чтения + """ + try: + with open(file_path, 'rb') as file: + return file.read() + except FileNotFoundError as e: + raise FileNotFoundError(f"Файл не найден: {file_path}") from e + except PermissionError as e: + raise PermissionError(f"Нет прав на чтение файла: {file_path}") from e + except Exception as e: + raise Exception(f"Ошибка при чтении бинарного файла: {file_path}") from e + +def write_txt_file(data: str, file_path: str) -> None: + """ + Сохраняет текстовые данные в файл + :param data: Текст который нужно записать в файл + :param file_path: Путь к файлу + :return: None + :raises FileNotFoundError: Если не удалось найти или создать файл по указанному пути + :raises PermissionError: Если нет прав на запись в файл + :raises Exception: При других ошибках записи + """ + try: + with open(file_path, 'w', encoding='utf-8') as file: + file.write(data) + except FileNotFoundError as e: + raise FileNotFoundError(f"Файл не найден: {file_path}") from e + except PermissionError as e: + raise PermissionError(f"Нет прав на запись в файл: {file_path}") from e + except Exception as e: + raise Exception(f"Ошибка при записи файла ммм: {file_path}") from e From b715a1ed1eb00175b641af2d9ed1ed86483c8dfe Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:31:02 +0400 Subject: [PATCH 06/10] =?UTF-8?q?=D0=94=D0=BE=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B1=D0=B8=D0=BD=D0=B0=D1=80=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- file_work.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/file_work.py b/file_work.py index a3821c0ca..bb5366f74 100644 --- a/file_work.py +++ b/file_work.py @@ -76,3 +76,23 @@ def write_txt_file(data: str, file_path: str) -> None: raise PermissionError(f"Нет прав на запись в файл: {file_path}") from e except Exception as e: raise Exception(f"Ошибка при записи файла ммм: {file_path}") from e + +def write_bytes_file(file_path: str, data: bytes) -> None: + """ + Сохраняет бинарные данные в файл + :param file_path: Путь к файлу + :param data: Бинарные данные, которые нужно записать + :return: None + :raises FileNotFoundError: Если не удалось найти или создать файл по указанному пути + :raises PermissionError: Если нет прав на запись в файл + :raises Exception: При других ошибках записи + """ + try: + with open(file_path, 'wb') as file: + file.write(data) + except FileNotFoundError as e: + raise FileNotFoundError(f"Файл не найден: {file_path}") from e + except PermissionError as e: + raise PermissionError(f"Нет прав на запись в файл: {file_path}") from e + except Exception as e: + raise Exception(f"Ошибка при записи файла: {file_path}") from e \ No newline at end of file From 61039beb4f3e3f98c9f3e3ab278d42138c0ad639 Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:32:51 +0400 Subject: [PATCH 07/10] =?UTF-8?q?=D0=A4=D0=B0=D0=B9=D0=BB=20=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- settings.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 settings.json diff --git a/settings.json b/settings.json new file mode 100644 index 000000000..65b5a80bd --- /dev/null +++ b/settings.json @@ -0,0 +1,8 @@ +{ + "text": "text.txt", + "encrypt_text": "encrypt_text.txt", + "decrypt_text": "decrypt_text.txt", + "encrypt_sym_key": "encrypt_sym_key.txt", + "private_key": "private_key.pem", + "public_key": "public_key.pem" +} \ No newline at end of file From bcce63904a85b12576ad541a28570970dc0ccd60 Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:33:56 +0400 Subject: [PATCH 08/10] =?UTF-8?q?=D0=9E=D1=80=D0=B8=D0=B3=D0=B8=D0=BD?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D1=82=D0=B5=D0=BA=D1=81?= =?UTF-8?q?=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- text.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 text.txt diff --git a/text.txt b/text.txt new file mode 100644 index 000000000..e74b9b5d3 --- /dev/null +++ b/text.txt @@ -0,0 +1 @@ +Криптография — это наука о методах обеспечения конфиденциальности, целостности и аутентичности информации путем преобразования данных в форму, недоступную для понимания посторонними. Её история уходит корнями в древность: первые криптографические методы использовались ещё в Древнем Египте и Месопотамии, где применялись простые шифры для защиты важных сообщений. В эпоху античности известным примером стал шифр Цезаря, основанный на сдвиге букв алфавита на фиксированное число позиций. Средневековье принесло более сложные методы, такие как полиалфавитные шифры, предложенные Леоном Баттистой Альберти, которые значительно повысили стойкость шифрования. С развитием технологий криптография перешла от ручных методов к машинным, особенно во время Второй мировой войны, когда немецкая шифровальная машина "Энигма" и её взлом британскими специалистами, включая Алана Тьюринга, стали поворотным моментом в истории криптоанализа. Современная криптография опирается на сложные математические алгоритмы, такие как RSA, основанный на проблеме факторизации больших чисел, и ECC, использующий свойства эллиптических кривых. Симметричные шифры, например AES, обеспечивают высокую скорость шифрования, а асимметричные — безопасный обмен ключами. Криптография также лежит в основе цифровых подписей, хеш-функций и протоколов защиты данных в интернете, таких как TLS. С появлением квантовых компьютеров возникли новые вызовы, поскольку они потенциально способны взломать многие современные алгоритмы, что стимулирует развитие постквантовой криптографии. Таким образом, криптография остаётся динамичной и критически важной областью. \ No newline at end of file From b8250d6dd59670d60bd2e1f6ecf65d3eb4d63e34 Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:43:46 +0400 Subject: [PATCH 09/10] =?UTF-8?q?=D0=9A=D0=BE=D0=BD=D1=81=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=BE=D0=B5=20=D0=BF=D1=80=D0=B8=D0=BB=D0=BE=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 app.py diff --git a/app.py b/app.py new file mode 100644 index 000000000..1f8587bc4 --- /dev/null +++ b/app.py @@ -0,0 +1,109 @@ +from serialize import * +from asymmetric_alg import AsymCipherManager +from symmetric_alg import SymCipherManager +from file_work import * + + +class HybridCryptosystem: + def __init__(self): + self._initialize_settings() + + def _initialize_settings(self) -> None: + """Инициализация настроек приложения""" + try: + self._settings = read_json_file("settings.json") + self._is_running = True + except Exception as e: + print("Ошибка: Не удалось загрузить файл настроек (settings.json)") + self._is_running = False + + def _display_menu(self) -> None: + """Отображение меню приложения""" + menu_items = [ + "\nВыберите действие:", + "1 - Сгенерировать ключи", + "2 - Зашифровать текст симметричным ключом", + "3 - Расшифровать текст", + "4 - Выход\n" + ] + print("\n".join(menu_items)) + + def _handle_key_generation(self) -> None: + """Обработка генерации ключей""" + try: + # Генерация ключей + private_key, public_key = AsymCipherManager.generate_rsa_keys() + symmetric_key = SymCipherManager.generate_sm4_key() + + # Сохранение ключей + serialize_public_key(self._settings["public_key"], public_key) + serialize_private_key(self._settings["private_key"], private_key) + + # Шифрование и сохранение симметричного ключа + encrypted_key = AsymCipherManager.encrypt_key(symmetric_key, public_key) + serialize_sym_key(self._settings["encrypt_sym_key"], encrypted_key) + + print("\n[Успех] Ключи сгенерированы и сохранены") + except Exception as e: + print(f"\n[Ошибка] Генерация ключей: {e}") + + def _handle_encryption(self) -> None: + """Обработка шифрования текста""" + try: + # Получение ключей + encrypted_key = deserialize_sym_key(self._settings["encrypt_sym_key"]) + private_key = deserialize_private_key(self._settings["private_key"]) + symmetric_key = AsymCipherManager.decrypt_key(encrypted_key, private_key) + + # Шифрование текста + text = read_bin_file(self._settings["text"]) + encrypted_text = SymCipherManager.encrypt_sm4(text, symmetric_key) + write_bytes_file(self._settings["encrypt_text"], encrypted_text) + + print("\n[Успех] Текст зашифрован") + except Exception as e: + print(f"\n[Ошибка] Шифрование текста: {e}") + + def _handle_decryption(self) -> None: + """Обработка дешифрования текста""" + try: + # Получение ключей + encrypted_key = deserialize_sym_key(self._settings["encrypt_sym_key"]) + private_key = deserialize_private_key(self._settings["private_key"]) + symmetric_key = AsymCipherManager.decrypt_key(encrypted_key, private_key) + + # Дешифрование текста + encrypted_text = read_bin_file(self._settings["encrypt_text"]) + decrypted_text = SymCipherManager.decrypt_sm4(encrypted_text, symmetric_key) + write_txt_file(decrypted_text.decode("UTF-8"), self._settings["decrypt_text"]) + + print("\n[Успех] Текст расшифрован") + except Exception as e: + print(f"\n[Ошибка] Дешифрование текста: {e}") + + def console_app(self) -> None: + """Основной цикл работы приложения""" + if not self._is_running: + return + + while self._is_running: + self._display_menu() + user_choice = input("Ваш выбор: ").strip() + + match user_choice: + case "1": + self._handle_key_generation() + case "2": + self._handle_encryption() + case "3": + self._handle_decryption() + case "4": + self._is_running = False + print("\nЗавершение работы программы...") + case _: + print("\n[Ошибка] Неверный ввод. Выберите пункт 1-4") + + +if __name__ == "__main__": + app = HybridCryptosystem() + app.console_app() \ No newline at end of file From 0c3ba18cdb51f1526170695a70e594035c12686d Mon Sep 17 00:00:00 2001 From: SeredovaSophia <162325967+SeredovaSophia@users.noreply.github.com> Date: Sat, 7 Jun 2025 20:45:35 +0400 Subject: [PATCH 10/10] =?UTF-8?q?=D0=A0=D0=B5=D0=B7=D1=83=D0=BB=D1=8C?= =?UTF-8?q?=D1=82=D0=B0=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- decrypt_text.txt | 1 + encrypt_sym_key.txt | Bin 0 -> 256 bytes encrypt_text.txt | Bin 0 -> 3024 bytes private_key.pem | 27 +++++++++++++++++++++++++++ public_key.pem | 9 +++++++++ 5 files changed, 37 insertions(+) create mode 100644 decrypt_text.txt create mode 100644 encrypt_sym_key.txt create mode 100644 encrypt_text.txt create mode 100644 private_key.pem create mode 100644 public_key.pem diff --git a/decrypt_text.txt b/decrypt_text.txt new file mode 100644 index 000000000..e74b9b5d3 --- /dev/null +++ b/decrypt_text.txt @@ -0,0 +1 @@ +Криптография — это наука о методах обеспечения конфиденциальности, целостности и аутентичности информации путем преобразования данных в форму, недоступную для понимания посторонними. Её история уходит корнями в древность: первые криптографические методы использовались ещё в Древнем Египте и Месопотамии, где применялись простые шифры для защиты важных сообщений. В эпоху античности известным примером стал шифр Цезаря, основанный на сдвиге букв алфавита на фиксированное число позиций. Средневековье принесло более сложные методы, такие как полиалфавитные шифры, предложенные Леоном Баттистой Альберти, которые значительно повысили стойкость шифрования. С развитием технологий криптография перешла от ручных методов к машинным, особенно во время Второй мировой войны, когда немецкая шифровальная машина "Энигма" и её взлом британскими специалистами, включая Алана Тьюринга, стали поворотным моментом в истории криптоанализа. Современная криптография опирается на сложные математические алгоритмы, такие как RSA, основанный на проблеме факторизации больших чисел, и ECC, использующий свойства эллиптических кривых. Симметричные шифры, например AES, обеспечивают высокую скорость шифрования, а асимметричные — безопасный обмен ключами. Криптография также лежит в основе цифровых подписей, хеш-функций и протоколов защиты данных в интернете, таких как TLS. С появлением квантовых компьютеров возникли новые вызовы, поскольку они потенциально способны взломать многие современные алгоритмы, что стимулирует развитие постквантовой криптографии. Таким образом, криптография остаётся динамичной и критически важной областью. \ No newline at end of file diff --git a/encrypt_sym_key.txt b/encrypt_sym_key.txt new file mode 100644 index 0000000000000000000000000000000000000000..9cfc67d1f5dd655e74e7875a03b08a36419baae7 GIT binary patch literal 256 zcmV+b0ssCPZj1xt$Bh5J+;)Q;9`2U$`@ff3K)jGjSczlCF4H2r-_AUG* z&>csCZP&~?2j)yol}K`>HIeO;K6Kpn1$w75S_K_DWqpjOu0AY&CH;IeBTFcJbX%S4 z#ByhAEip7VRX}guRZG1ZlSJ#yNp*B~u@ShdA2mo0kv!8^7@7qL-sM+0H;T13z4$l* zVwnILPBbjWSp%Nw{vu}|U0)(tW}m7mlOEOK?p%kb7#G_ GLr40xymV6l literal 0 HcmV?d00001 diff --git a/encrypt_text.txt b/encrypt_text.txt new file mode 100644 index 0000000000000000000000000000000000000000..5538530645f72548d63749eb38ce9b4424f83ed6 GIT binary patch literal 3024 zcmV;>3orC~S|JfV6}&)1mFZi>VLK3m;)K?3|E(Yh=rhap^3c>)LPH!4Ye5JV6Obo` zM@9NA7U_!d4*h(_9vH{(9<6CXx@!Vsw1oR-M@e_p+6=^+NmdvF9u*YuCJ*4F>oEyt z^aCRJl>4vuufg>NzVyWM0#qqLj-ts>L-CnhVAKPbTliJ%kH>dhPNoE+dtRu@l!hh7 zc+INx8_2-~2kLgMTrETO6dYM2XB(M8>f(=y49e)7!?k%lGqonBPn8tZ)|{7m0<(bC z%c*n98F{$saPJHj$aZ`K4wa?C>~I{iO1RliC2CvXQhtF>!Z1`6=&tB{#&mwuGrHyk zP)%%gu5IJVfnbI)M(N7Lgd-%uf|D_jni$|DI#D1?M1M2Ijn-`)=8;}0)^OX9Th~j- z*9Fpvw&m_jY_ zW73v?rrQ_b2f<2bBF-QauZ{oO$ht$~wI)cX$X3s#=k` zyaXfIUs!Adozq@Stz138nJ-q=bs0$Nuc`^An!Kwi=eC}n-MhUisnNVA4Nv2}GRoVz z(63c7^5=qk;q(&U~e5jsX)aB}NV$wfNNAlv5Q@5#ANTG6($rL)YY#nI&CNBu>jTm~!u zdDTrHy)P=YMa$h}4NU{#qyTSz{>XGAvs5YW;PwrVzVkoQI znfUd;@?^}VLE3@^lRn%vA>Ff!7_$Us!9nu*^-aC_&xiK0Kj*pvqWbL~~!WzJ+}*&p<8v@KVO#z3t|_*;Q`qN z_!_l~ZImAP(bF?}XmkWb%+=%o^$0cc;d7$0by7j3+}^SVm zr?j7u?78<^7oM{9{@-)_7256_2meoi?>|s8$ZGs0_tXLFD2EGpu?r5@Ca<3!M&f;# zzGq$J=^RfrhDc@29sPZ>D%cGFXEHqY_;BIV<+hsFOfs$KqlZzdS^RLZNwu*n6GJb7 zzpYaSf%@L+1^EAcD!Kch(72M=#seswHjJ|Q zfriN-_ZAw5L_wYij>7V2FOJFA(fT5Z-ds_kxsNP8u;UhmCoz6H{c3ot!uX&;JGoTk z-eNxxO5OJ?baiOwh5o@)%MQGTnU8;?Rt`aT_Ei&r>IfF8mX494^XXhpJTvtZ|jA)sFl0t#R zyWnzDUNG?-gzLU>vD1C|)FIi!@Jg-tN`GwqI_O?37Unf3JbljIXNAG6RfzD2bn3E0 zj^(`aC;x~E?o`YNbq|alE>t4S_GWjRB$s)HNJU|I(U>F^5)jQ5ma-h*!M^#6g@mL* zSjn@yRf>Lz&ZKI9Dm%3~Q4IW%mIoY2Pz44#J-vgPxuCrYGYmc2-!9NOUzJH-U-j6V z*cDl++bj~o9k4PXzx~GKWnRvfEscOnjq-NM2x*<`n?c8Kp9e5n)ErV;y&r zHHm~CUDw2C2X1b>UCCD`y0)=d(946SC(BbyYJ7GNhK(Ie0g2*kL*9gJB&b9oN?Bj~ zfh?rOfOF) zYt-Y)c$8WIeib>jFqTDPU~;GlLS9r=T<-RWF|mryI^$hd75suC%={2e8Zm#QxIxGV zrg&~bAhXtx>NV)1p`Y_iC{wlzF9jWiX3F!X%mM!=I(t2lHV&#vh~ZLEP!JOf*Fd*R zxr8}9R;!za5w|(2^hT*9BUa|PaQa%lZ)n1^uk&v2!&yMCfwfK7lEJXhMYl#2RBU0Us(Opl=>`_~&fcr^%&h0s(Jd}pAk zEKcg`^` zU;PVc(^^g>oJ){8j;kt%?U~tkQX@?5?kOEa50-4+EwuwSpn7G5m5|Q9Q zW)65TS!^Hq)@~*?I~h@zSH=+OBOdM&a;gxbOqln8fB=4h%+9FzU}PZ_GO~|r(%O9D z&2N^cTy`3qNvKQ3x`7RPc^0#8%FJ3(q$G4-4Zktw&!B&KN;Oxio27FMdMb?!p_m6I zo^gDKW!*WVRN3E9oBRB{&7mq{c|lg;$&TpS(-UA}LtfBtO)m8k_bOqwTmw`rtgLU&8*mziTA#+29eKfB*=R S<&(hK(L&Fb3>03lP&!34AM6(Z literal 0 HcmV?d00001 diff --git a/private_key.pem b/private_key.pem new file mode 100644 index 000000000..138db6cc2 --- /dev/null +++ b/private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxPajp2C5jFicPJlb1YtwDoZ6lHVPzLGjnZNg/Rvd3hZHkAyq +Ug0ews/j8L1QD6vWz1rOBaLfB+ksQFuF2aXMoIuy87G7xKFlJUdaxScqQ7dm5Js7 +cMYD5NuS0GgHBxQ6gstHX3GfkVUK4bec1vcLDDUasm3Gr1PGI0DOpc81HK5QTo+Y +9Tah2tF6CpXnraM+WeoGqJ5ZVSBFPTgdUyJaiK/vrmfx5UE7f6CYhBEOXPdtJW2T +NftnRZwa8FH+DIGl3a3ImaAowlBCNUQhVWFH4JMNP9sFcTeKvfUUinsUmtY1teBI +d7/1jb73uRUn2LV5/7F5gvLLKU5k77dgB33bOwIDAQABAoIBAEsrpkHXFHmPx/EI +xpe1Y8rnYBkQvKfuk/crrDRtUjvUXPOJIee2wiqvlNroJYoVlyIEEeTsyBoIz66w +P2FVecc8Ccwf5P2iayvTE71yuRqnAEn3RLRBnnLVqi6HxUbaXYpVcqPmhXO99S04 +Gk+gcULzcYDvjIiVfGUv8q4taqPK51Saky4RsHv60KkIVTiVygx9M5jZJURquNXj +w7SOtMIyCmlScXmq3Q9YKv0cSh0UBQgRIbbA82KkMqMOf3+4Jjs6X3qIPjiHEbXs +p9DQa59rjmUSM23k9sDx7mpYoByG0zJHeCB6hG5ZRZ1Ozkc9xuuOAlakLZuL+37a ++x/GncECgYEA8c2diPzZ3hBdbbruPYov2Ep8eSaflLjhu7fnsVce1VXJfknjNMql +JPns7RVjmdkYO3PkCjDs1mi7B8TZ7R/JYuPVw7fDyNUt6SJ2MnhnYI2I9t+K8NZj +s5JjvXAxiHk6//ZK8okb9OYFOK6RxAtwWXFN707SRgO+UzmWQ8e86rMCgYEA0IcR +LeQWhqZZ4XK7DBluNpZLCgcAtiRz85dH49BDyH7bV4ZeD/dQz8uyf9vU+HOtt3Ha +VVAyM/ksWeGkVmC1Ftk/xnBghb9PCCpHq/4YMetYjS2+0aqV5CD1CVqnxFSg/EG/ +EfjES5Ew4g9CDaRzsfZzHmapoHTuCX6MRZyMMVkCgYA+3dWaexrt2FViJRqx106v +LlaEbR1KXnMaCitr+RmkH6S+d9lhrVoYbf5CebAmnMHnGy9r0uKQsDQIRg7ezsfe +NRwrwYhem8ZO+c2/O3ytJr84aFBIY4USd/oEk7ndIJ/NUqyTuEATgQZUgVaWoN65 +8nJvyI908p42Jx/BSZn9bwKBgQDKWtfL7bQCVHmSMpDay+7M4AnPoD4LgtJWhu6H +Xzn33Uqi48xxt/DexO/h7YT82Nyx0LUr5tfg4aMtUa7094Gju4yM186C28Qoy0aj +277E6noS/lpXAi/UojrHKgb1mZ5jTLXLDdoG7s0+Acp6jKSNBPhvfvaKtA2ufvRG +NQVCeQKBgQCMMPqy0RCpfW2uzgxahOq2f9QFieivEfhOIhm2J09uw9XbluCh3bw4 +MTbiApjuhOHkOffXBeIkCoRgqnwj/+wuXYIiYtx5XpeX/pPTlqw7n5g7bQ2zKfw8 +Ew/8dZD2zG1voWcoM3OoWzuVozqJScagbp1N5XYiIiqu2FfQBx25vg== +-----END RSA PRIVATE KEY----- diff --git a/public_key.pem b/public_key.pem new file mode 100644 index 000000000..8ca4666b6 --- /dev/null +++ b/public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxPajp2C5jFicPJlb1Ytw +DoZ6lHVPzLGjnZNg/Rvd3hZHkAyqUg0ews/j8L1QD6vWz1rOBaLfB+ksQFuF2aXM +oIuy87G7xKFlJUdaxScqQ7dm5Js7cMYD5NuS0GgHBxQ6gstHX3GfkVUK4bec1vcL +DDUasm3Gr1PGI0DOpc81HK5QTo+Y9Tah2tF6CpXnraM+WeoGqJ5ZVSBFPTgdUyJa +iK/vrmfx5UE7f6CYhBEOXPdtJW2TNftnRZwa8FH+DIGl3a3ImaAowlBCNUQhVWFH +4JMNP9sFcTeKvfUUinsUmtY1teBId7/1jb73uRUn2LV5/7F5gvLLKU5k77dgB33b +OwIDAQAB +-----END PUBLIC KEY-----