Python Tkinter:开发一款文件加密解密小工具

在这个信息泄露风险日益增加的时代,使用文件加密工具对于保护个人隐私和企业机密至关重要。

本文介绍了一款小工具——encryptDecrypt,它不仅提供了一个易于使用的图形界面,简化了加密和解密过程,还确保了数据的安全性,帮助用户遵守数据保护法规,同时尊重和保障了信息的隐私性。

What's NEW:

GitHub正式发布V1.0.0,欢迎使用:https://github.com/AICVHub/encryptDecrypt.giticon-default.png?t=N7T8https://github.com/AICVHub/encryptDecrypt.git

同时,GitHub上面还提供了针对linux和windows两个平台上打包好的可执行文件,也欢迎大家从release里面下载使用:


1. 简介

该加密/解密工具的特性主要体现在以下几个方面:

  • 数据保护: 随着网络攻击和数据泄露事件的日益增多,加密是保护数据不被未授权访问的有效手段。

  • 遵守法规: 许多国家和地区都有严格的数据保护法规,如欧盟的通用数据保护条例(GDPR),加密工具帮助组织和个人遵守这些法规。

  • 隐私尊重: 对于处理敏感信息的个人和企业来说,加密是尊重用户隐私和建立信任的重要方式。

  • 便捷操作: 该工具提供了一个简单易用的图形界面,使得没有专业加密知识的用户也能轻松进行文件的加密和解密,降低了使用门槛。

  • 灵活性: 用户可以根据自己的需求生成和加载密钥,对不同文件使用不同的加密策略,提供灵活的加密选项。

  • 本地化处理: 加密和解密过程在用户本地计算机上完成,无需上传数据到第三方服务器,减少了数据在传输过程中的风险。

  • 多平台支持:提供了windows和linux两个平台的预编译包,也提供了源码,可以在任何平台使用。

2. 方法

2.1. 导入模块

  • tkinter as tk: 用于创建GUI应用程序。
  • filedialog: Tkinter的文件对话框模块,用于打开文件选择对话框。
  • messagebox: 用于显示消息框。
  • ttk: 它们是Tkinter主题化的扩展,提供更现代的界面元素。
  • Fernet: 来自cryptography.fernet模块,用于创建安全的加密密钥。

2.2. 定义FileEncryptorDecryptor

这个类负责处理加密和解密的核心逻辑。

  • __init__: 初始化类实例,设置keyfernet对象为None
  • generate_key: 生成一个新的加密密钥并返回。
  • save_key: 将加密密钥保存到文件中。
  • load_key: 从文件中加载加密密钥,并初始化Fernet对象。
  • encrypt_file: 加密文件,如果尚未设置Fernet对象,则生成新密钥并保存。
  • decrypt_file: 解密文件,需要先加载密钥,如果密钥不正确会捕获异常。

2.3. 定义EncryptDecryptApp

这个类是Tkinter应用程序的主要入口点,负责创建和管理GUI组件。

  • __init__: 初始化GUI窗口和组件,包括按钮和框架。
  • encrypt_file: 定义加密文件的逻辑,包括打开文件选择对话框、保存加密文件,并调用FileEncryptorDecryptor类的encrypt_file方法。
  • decrypt_file: 类似于encrypt_file,但用于解密文件。
  • load_key: 打开密钥文件选择对话框,并调用FileEncryptorDecryptor类的load_key方法。

2.4. GUI组件

  • self.frame: 创建一个Ttk框架作为按钮的容器。
  • self.encrypt_button: 加密按钮,点击时会触发文件加密操作。
  • self.decrypt_button: 解密按钮,点击时会触发文件解密操作。
  • self.key_load_button: 加载密钥按钮,点击时会打开文件对话框让用户选择密钥文件。

2.5. 主程序

  • 检查__name__ == '__main__'确保当脚本被直接运行时才创建Tkinter窗口和应用实例,并启动事件循环。

2.6. 错误处理

代码中使用了try...except块来捕获并处理可能发生的异常,例如文件操作错误、密钥加载错误等,并通过messagebox.showerror向用户显示错误信息。

2.7. 用户交互

  • 用户可以通过点击按钮来选择要加密或解密的文件。
  • 加密操作会生成一个新的密钥(如果尚未生成),并提示用户保存。
  • 解密操作需要用户先加载正确的密钥文件。

2.8. 密钥管理

  • 密钥以二进制形式保存和加载,通常保存在扩展名为.key的文件中。

3. 代码

主要的代码如下,包括了FileEncryptorDecryptor和EncryptDecryptApp,分别负责处理加密和解密的核心逻辑以及负责创建和管理GUI组件:

class FileEncryptorDecryptor:
    def __init__(self):
        self.key = None
        self.fernet = None

    def generate_key(self):
        self.key = Fernet.generate_key()
        return self.key

    def save_key(self, key, key_filename='key.key'):
        try:
            with open(key_filename, 'wb') as key_file:
                key_file.write(key)
        except Exception as e:
            messagebox.showerror("错误", f"保存密钥时发生错误: {e}")

    def load_key(self, key_filename):
        try:
            with open(key_filename, 'rb') as key_file:
                key = key_file.read()
            self.fernet = Fernet(key)
        except FileNotFoundError:
            messagebox.showerror("错误", "密钥文件未找到,请确保密钥文件存在。")
        except Exception as e:
            messagebox.showerror("错误", f"加载密钥时发生错误: {e}")

    def encrypt_file(self, input_filename, output_filename):
        if not self.fernet:
            self.fernet = Fernet(self.generate_key())
            self.save_key(self.key)

        try:
            with open(input_filename, 'rb') as input_file:
                content = input_file.read()
            encrypted_content = self.fernet.encrypt(content)
            with open(output_filename, 'wb') as output_file:
                output_file.write(encrypted_content)
            messagebox.showinfo("成功", "文件已加密。")
        except Exception as e:
            messagebox.showerror("错误", f"加密过程中发生错误: {e}")

    def decrypt_file(self, input_filename, output_filename):
        if not self.fernet:
            messagebox.showerror("错误", "请先加载密钥。")

        try:
            with open(input_filename, 'rb') as input_file:
                encrypted_content = input_file.read()
            decrypted_content = self.fernet.decrypt(encrypted_content)
            with open(output_filename, 'wb') as output_file:
                output_file.write(decrypted_content)
            messagebox.showinfo("成功", "文件已解密。")
        except Fernet.InvalidToken:
            messagebox.showerror("错误", "解密失败,密钥可能不正确。")
        except Exception as e:
            messagebox.showerror("错误", f"解密过程中发生错误: {e}")

class EncryptDecryptApp:
    def __init__(self, root):
        self.root = root
        self.root.title("文件加密/解密工具")
        self.ed = FileEncryptorDecryptor()

        self.frame = ttk.Frame(self.root, padding="3 3 12 12")
        self.frame.grid(column=0, row=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        self.encrypt_button = ttk.Button(self.frame, text="加密文件", command=self.encrypt_file)
        self.encrypt_button.grid(column=0, row=0, padx=10, pady=10)

        self.decrypt_button = ttk.Button(self.frame, text="解密文件", command=self.decrypt_file)
        self.decrypt_button.grid(column=1, row=0, padx=10, pady=10)

        self.key_load_button = ttk.Button(self.frame, text="加载密钥", command=self.load_key)
        self.key_load_button.grid(column=2, row=0, padx=10, pady=10)

    def encrypt_file(self):
        input_filename = filedialog.askopenfilename(
            title="选择要加密的文件",
            filetypes=[("所有文件", "*.*")]
        )
        if not input_filename:
            return

        output_filename = filedialog.asksaveasfilename(
            title="保存加密文件",
            defaultextension=".enc",
            filetypes=[("加密文件", "*.enc")]
        )
        if not output_filename:
            return

        self.ed.encrypt_file(input_filename, output_filename)

    def decrypt_file(self):
        input_filename = filedialog.askopenfilename(
            title="选择要解密的文件",
            filetypes=[("加密文件", "*.enc")]
        )
        if not input_filename:
            return

        output_filename = filedialog.asksaveasfilename(
            title="保存解密文件",
            defaultextension=".txt",
            filetypes=[("解密文件", "*")]
        )
        if not output_filename:
            return

        self.ed.decrypt_file(input_filename, output_filename)

    def load_key(self):
        key_filename = filedialog.askopenfilename(
            title="选择密钥文件",
            filetypes=[("密钥文件", "*.key")]
        )
        if not key_filename:
            return

        self.ed.load_key(key_filename)

完整代码见GitHub,或直接使用打包好的程序

4. 软件运行截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AICVHub

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值