Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions lab_3/asym_RSA.py
Original file line number Diff line number Diff line change
@@ -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))


19 changes: 19 additions & 0 deletions lab_3/config.py
Original file line number Diff line number Diff line change
@@ -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}")
2 changes: 2 additions & 0 deletions lab_3/decrypted_text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
В современном мире программирование стало фундаментальным навыком, сравнимым с чтением и письмом. Умение понимать язык компьютеров открывает невероятные возможности — от создания сайтов до разработки искусственного интеллекта. Каждая строка кода превращает абстрактную идею в работающее приложение или полезный сервис.
Изучение программирования развивает логическое мышление, учит решать сложные задачи путем их разбиения на более простые части. Этот навык полезен не только разработчикам, но и ученым, аналитикам, дизайнерам. В эпоху цифровизации понимание принципов работы ПО становится конкурентным преимуществом на рынке труда.
Empty file added lab_3/encripted_text.bin
Empty file.
Binary file added lab_3/encrypted_text.bin
Binary file not shown.
45 changes: 45 additions & 0 deletions lab_3/file_manager.py
Original file line number Diff line number Diff line change
@@ -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}")
35 changes: 35 additions & 0 deletions lab_3/generate_keys.py
Original file line number Diff line number Diff line change
@@ -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()

30 changes: 30 additions & 0 deletions lab_3/main.py
Original file line number Diff line number Diff line change
@@ -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()
1 change: 1 addition & 0 deletions lab_3/nonce.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
F�s�����Pޒ�.�
27 changes: 27 additions & 0 deletions lab_3/private_key.pem
Original file line number Diff line number Diff line change
@@ -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-----
9 changes: 9 additions & 0 deletions lab_3/public_key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtU3ADpdTZ1jmGtfEFyPA
q6I2kgaWumRworK4ogiMKhsFaCzyDDkIIDXB2bhR+rwS7Z0Zfrs22HhD68sBklag
9RGT4jorgC/HR9zAjA76fghzMdAFgR5y03rh8A49r9eTOlbc4QZsh/tXBHWzhLuC
Lf/UUxPtFz9TUBEKDOLPqhL7xdcuLyiZK4153C8e6Qu3HsuXsSbvIRgvu4MHmGZh
eAV1H9DPFxJWdHCcOKSdcl/Y0D/DTrj/ID0Rdsux3gRcxjbW550jUOljcPntyccW
URg2ybnHQT48U3ThmcNJbol9HpTsFnGqXWWko1UeJAMiZT2C5XQUMflFRy2nr33/
ZQIDAQAB
-----END PUBLIC KEY-----
86 changes: 86 additions & 0 deletions lab_3/scenaries.py
Original file line number Diff line number Diff line change
@@ -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")
9 changes: 9 additions & 0 deletions lab_3/settings.json
Original file line number Diff line number Diff line change
@@ -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"
}
36 changes: 36 additions & 0 deletions lab_3/sym_ChaCha20.py
Original file line number Diff line number Diff line change
@@ -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)


1 change: 1 addition & 0 deletions lab_3/sym_key.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
��"۲5�,��ޡh(�-?�}��W�ۼO]�߆�"=�r�-�q\ivb �L|�'��x�$W�=�����mS0���?>�#�=�7c�>U���F�i-+͢�ǎ�%�"�0�2��F:K��`�9�� e�Uq�S��>C�+�&��p/[��~rX0 ����s�Uf�!d�Y���e�~���0 �#؜f�kB �ox�#��S�?,���]�O;�G2Zn@��i�vD� ݡ��o7!C঴7kp� N�=
2 changes: 2 additions & 0 deletions lab_3/text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
В современном мире программирование стало фундаментальным навыком, сравнимым с чтением и письмом. Умение понимать язык компьютеров открывает невероятные возможности — от создания сайтов до разработки искусственного интеллекта. Каждая строка кода превращает абстрактную идею в работающее приложение или полезный сервис.
Изучение программирования развивает логическое мышление, учит решать сложные задачи путем их разбиения на более простые части. Этот навык полезен не только разработчикам, но и ученым, аналитикам, дизайнерам. В эпоху цифровизации понимание принципов работы ПО становится конкурентным преимуществом на рынке труда.