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}")