Skip to content
Closed
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
1 change: 1 addition & 0 deletions decrypted_text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Она несла в руках отвратительные, тревожные желтые цветы. Черт их знает, как их зовут, но они первые почему-то появляются в Москве. И эти цветы очень отчетливо выделялись на черном ее весеннем пальто. Она несла желтые цветы! Нехороший цвет. Она повернула с Тверской в переулок и тут обернулась. Ну, Тверскую вы знаете? По Тверской шли тысячи людей, но я вам ручаюсь, что увидела она меня одного и поглядела не то что тревожно, а даже как будто болезненно. И меня поразила не столько ее красота, сколько необыкновенное, никем не виданное одиночество в глазах!
Binary file added encrypted_text.txt
Binary file not shown.
74 changes: 74 additions & 0 deletions lab_3/asymmetrical.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from cryptography.hazmat.primitives import padding, hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding


class AsymmetricCryptography:
"""
Class for asymmetric encryption using RSA
"""
def __init__(self, private_key_path: str, public_key_path: str) -> None:
"""
Initializes AsymmetricCryptography class object
:param private_key_path: path for saving private key
:param public_key_path: path for saving public key
"""
self.private_key_path = private_key_path
self.public_key_path = public_key_path

@staticmethod
def generate_key() -> tuple[rsa.RSAPrivateKey, rsa.RSAPublicKey]:
"""
Generates a pair of RSA keys
:return: tuple of private and public keys
"""
try:
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
return private_key, public_key
except Exception as e:
print("Error:", e)
raise

@staticmethod
def encrypt(data: bytes, public_key: rsa.RSAPublicKey) -> bytes:
"""
Encrypts data using a public RSA key
:param data: data to encrypt
:param public_key: public key for encryption
:return: encrypted data
"""
try:
c_data = public_key.encrypt(
data,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
)
)
return c_data
except Exception as e:
print("Error:", e)
raise

@staticmethod
def decrypt(data: bytes, private_key: rsa.RSAPrivateKey) -> bytes:
"""
Decrypts data using a private RSA key
:param data: encrypted data
:param private_key: private key for decryption
:return: decrypted data
"""
try:
dc_data = private_key.decrypt(
data,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
)
)
return dc_data
except Exception as e:
print("Error:", e)
raise
81 changes: 81 additions & 0 deletions lab_3/crypto_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from cryptography.hazmat.primitives import padding, hashes
from cryptography.hazmat.primitives.asymmetric import padding

from asymmetrical import AsymmetricCryptography
from serialize import Serialization
from symmetrical import SymmetricCryptography
from work_file import *


class HybridCryptoSystem:
"""
Class implementing a hybrid crypto system using SEED (symmetric) and RSA (asymmetric) algorithms
"""

def __init__(self, symmetric_key_path: str, private_key_path: str, public_key_path: str) -> None:
"""
Initializes HybridCryptoSystem class object
:param symmetric_key_path: path for saving symmetrical key
:param private_key_path: path for saving private key
:param public_key_path: path for saving public key
"""
self.block_size = 128
self.symmetric = SymmetricCryptography(symmetric_key_path)
self.asymmetric = AsymmetricCryptography(private_key_path, public_key_path)

def generate_keys(self, size: int) -> None:
"""
Generates key for hybrid method
:param size: size of keys
"""
try:
symmetric_key = self.symmetric.generate_key(size)
asymmetric_key = self.asymmetric.generate_key()
private_key, public_key = asymmetric_key

Serialization.save_private_key(self.asymmetric.private_key_path, private_key)
Serialization.save_public_key(self.asymmetric.public_key_path, public_key)
write_bytes(public_key.encrypt(symmetric_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
)
),
self.symmetric.key_path)
except Exception as e:
print("Error:", e)
raise

def encrypt(self, data_path: str, encrypted_data_path: str) -> None:
"""
Encrypts a file using a hybrid system
:param data_path: path to file with data
:param encrypted_data_path: path to file for saving encrypted data
"""
try:
text = bytes(read_txt(data_path), "UTF-8")
key = Serialization.load_private_key(self.asymmetric.private_key_path)
symmetric_key = self.asymmetric.decrypt(read_bytes(self.symmetric.key_path), key)
c_text = self.symmetric.encrypt(text, symmetric_key)
write_bytes(c_text, encrypted_data_path)
except Exception as e:
print("Error:", e)
raise

def decrypt(self, data_path: str, decrypted_data_path: str) -> None:
"""
Decrypts a file using a hybrid system
:param data_path: path to file with data
:param decrypted_data_path: path to file for saving decrypted data
:return:
"""
try:
c_data = read_bytes(data_path)
key = Serialization.load_private_key(self.asymmetric.private_key_path)
symmetric_key = self.asymmetric.decrypt(read_bytes(self.symmetric.key_path), key)
dc_data = self.symmetric.decrypt(c_data, symmetric_key)
write_bytes(dc_data, decrypted_data_path)
except Exception as e:
print("Error:", e)
raise
42 changes: 42 additions & 0 deletions lab_3/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import argparse

from crypto_system import HybridCryptoSystem
from work_file import *


def main():
paths = read_json("settings.json")

main_parser = argparse.ArgumentParser()
group = main_parser.add_mutually_exclusive_group(required=True)
group.add_argument("-gen", "--generation", help="key generation mode", nargs='?', const=32, default=None, type=int,
choices=[16, 24, 32])
group.add_argument("-enc", "--encryption", help="encryption mode", action="store_true")
group.add_argument("-dec", "--decryption", help="decryption mode", action="store_true")

main_parser.add_argument("--symmetric-key", help="path to symmetric key", default=paths["symmetric_key"])
main_parser.add_argument("--secret-key", help="path to secret key", default=paths["secret_key"])
main_parser.add_argument("--public-key", help="path to public key", default=paths["public_key"])

args = main_parser.parse_args()

args.generation_flag = args.generation is not None

if args.generation_flag and args.generation is None:
args.generation = 32

match (args.generation_flag, args.encryption, args.decryption):
case (True, False, False):
key_size = args.generation
h = HybridCryptoSystem(args.symmetric_key, args.secret_key, args.public_key)
h.generate_keys(key_size)
case (False, True, False):
h = HybridCryptoSystem(args.symmetric_key, args.secret_key, args.public_key)
h.encrypt(paths["initial_file"], paths["encrypted_file"])
case (False, False, True):
h = HybridCryptoSystem(args.symmetric_key, args.secret_key, args.public_key)
h.decrypt(paths["encrypted_file"], paths["decrypted_file"])


if __name__ == '__main__':
main()
112 changes: 112 additions & 0 deletions lab_3/serialize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.serialization import (
load_pem_public_key,
load_pem_private_key,
)


class Serialization:
"""
Class for serializing and deserializing cryptographic keys
"""

@staticmethod
def save_symmetric_key(file_path: str, key: bytes) -> None:
"""
Saves the symmetric key to file
:param file_path: path to file to save
:param key: key to save
"""
try:
with open(file_path, "wb") as key_file:
key_file.write(key)
except Exception as e:
print("Error:", e)
raise

@staticmethod
def load_symmetric_key(file_path: str) -> bytes:
"""
Loads the symmetric key from file
:param file_path: path to file with key
:return: key
"""
try:
with open(file_path, "rb") as key_file:
return key_file.read()
except Exception as e:
print("Error:", e)
raise

@staticmethod
def save_private_key(path: str, private_key: rsa.RSAPrivateKey) -> None:
"""
Saves the private RSA key to a file
:param path: path to file to save
:param private_key: the RSA private key
"""
try:
with open(path, "wb") as private_out:
private_out.write(
private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
)
except Exception as e:
print("Error:", e)
raise

@staticmethod
def save_public_key(path: str, public_key: rsa.RSAPublicKey) -> None:
"""
Saves the public RSA key to a file
:param path: path to file to save
:param public_key: the RSA public key
"""
try:
with open(path, "wb") as public_out:
public_out.write(
public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
)
except Exception as e:
print("Error:", e)
raise

@staticmethod
def load_private_key(path: str) -> rsa.RSAPrivateKey:
"""
Loads a private RSA key from a file
:param path: the path to the file that contains the key
:return: the RSA private key
"""
try:
with open(path, "rb") as pem_in:
private_bytes = pem_in.read()
d_private_key = load_pem_private_key(
private_bytes,
password=None,
)
return d_private_key
except Exception as e:
print("Error:", e)

@staticmethod
def load_public_key(path: str) -> rsa.RSAPublicKey:
"""
Loads a public RSA key from a file
:param path: the path to the file that contains the key
:return: the RSA public key
"""
try:
with open(path, "rb") as pem_in:
public_bytes = pem_in.read()
d_public_key = load_pem_public_key(public_bytes)
return d_public_key
except Exception as e:
print("Error:", e)
8 changes: 8 additions & 0 deletions lab_3/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"symmetric_key": "symmetric_key.txt",
"public_key": "public.pem",
"secret_key": "private.pem",
"initial_file": "text.txt",
"encrypted_file": "encrypted_text.txt",
"decrypted_file": "decrypted_text.txt"
}
Loading