93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
from tkinter import messagebox, filedialog as fd
|
||
|
|
|
||
|
|
|
||
|
|
class CryptoTools:
|
||
|
|
"""Операции шифрования и расшифрования файлов."""
|
||
|
|
|
||
|
|
def __init__(self, crypto_manager, audit_logger):
|
||
|
|
self.crypto_manager = crypto_manager
|
||
|
|
self.audit_logger = audit_logger
|
||
|
|
|
||
|
|
def _generate_and_save_key(self) -> bytes | None:
|
||
|
|
key = self.crypto_manager.generate_key()
|
||
|
|
path = fd.asksaveasfilename(
|
||
|
|
title="Сохранить ключ шифрования",
|
||
|
|
defaultextension=".key",
|
||
|
|
filetypes=[("Key file", "*.key"), ("All files", "*.*")],
|
||
|
|
initialfile="encryption.key",
|
||
|
|
)
|
||
|
|
if not path:
|
||
|
|
return None
|
||
|
|
try:
|
||
|
|
Path(path).write_bytes(key)
|
||
|
|
except Exception as e:
|
||
|
|
messagebox.showerror("Сохранение ключа",
|
||
|
|
f"Не удалось сохранить ключ:\n{e}")
|
||
|
|
return None
|
||
|
|
messagebox.showinfo("Ключ сохранён", f"Ключ сохранён в:\n{path}")
|
||
|
|
return key
|
||
|
|
|
||
|
|
def _load_key_from_file(self) -> bytes | None:
|
||
|
|
path = fd.askopenfilename(
|
||
|
|
title="Выберите файл ключа",
|
||
|
|
filetypes=[("Key file", "*.key"), ("All files", "*.*")],
|
||
|
|
)
|
||
|
|
if not path:
|
||
|
|
return None
|
||
|
|
try:
|
||
|
|
return Path(path).read_bytes()
|
||
|
|
except Exception as e:
|
||
|
|
messagebox.showerror(
|
||
|
|
"Чтение ключа", f"Не удалось прочитать ключ:\n{e}")
|
||
|
|
return None
|
||
|
|
|
||
|
|
def _select_output_path(self, suggested: Path, title: str, defext: str, pattern: str) -> Path | None:
|
||
|
|
path = fd.asksaveasfilename(
|
||
|
|
title=title,
|
||
|
|
defaultextension=defext,
|
||
|
|
filetypes=[(f"*{defext}", pattern), ("All files", "*.*")],
|
||
|
|
initialdir=str(suggested.parent),
|
||
|
|
initialfile=suggested.name,
|
||
|
|
)
|
||
|
|
return Path(path) if path else None
|
||
|
|
|
||
|
|
def encrypt_file(self):
|
||
|
|
src = fd.askopenfilename(title="Выберите файл для шифрования")
|
||
|
|
if not src:
|
||
|
|
return
|
||
|
|
key = self._generate_and_save_key()
|
||
|
|
if key is None:
|
||
|
|
return
|
||
|
|
suggested = Path(src).with_suffix(Path(src).suffix + ".enc")
|
||
|
|
out = self._select_output_path(
|
||
|
|
suggested, "Сохранить зашифрованный файл", ".enc", "*.enc")
|
||
|
|
if out is None:
|
||
|
|
return
|
||
|
|
self.crypto_manager.encrypt_file(src, key, str(out))
|
||
|
|
self.audit_logger.log(f"Зашифрован файл → {out.name}")
|
||
|
|
messagebox.showinfo("Шифрование файла", f"Создан файл: {out}")
|
||
|
|
|
||
|
|
def decrypt_file(self):
|
||
|
|
enc = fd.askopenfilename(title="Выберите зашифрованный файл", filetypes=[
|
||
|
|
("Encrypted", "*.enc"), ("All files", "*.*")])
|
||
|
|
if not enc:
|
||
|
|
return
|
||
|
|
key = self._load_key_from_file()
|
||
|
|
if key is None:
|
||
|
|
return
|
||
|
|
suggested = Path(enc).with_suffix(".dec")
|
||
|
|
out = self._select_output_path(
|
||
|
|
suggested, "Сохранить расшифрованный файл", ".dec", "*.dec")
|
||
|
|
if out is None:
|
||
|
|
return
|
||
|
|
try:
|
||
|
|
self.crypto_manager.decrypt_file(enc, key, str(out))
|
||
|
|
except Exception as e:
|
||
|
|
messagebox.showerror("Расшифрование файла", f"Ошибка:\n{e}")
|
||
|
|
return
|
||
|
|
self.audit_logger.log(f"Расшифрован файл → {out.name}")
|
||
|
|
messagebox.showinfo("Расшифрование файла", f"Создан файл: {out}")
|