用Python编写Windows右键菜单小工具:实现文件快速加密与解密

宋时安
宋时安
发布时间:2026-11-13 | 5人浏览过
原创

详细讲解如何用Python编写一个Windows右键菜单小工具,实现对文件的快速加密与解密操作,包含完整代码、注册表配置和常见问题解决方案。

在Windows资源管理器中右键点击一个文件,直接选择"加密"或"解密"就能完成操作——这个功能可以用一个不到100行的Python脚本加上几条注册表配置实现。本文会带你完成从脚本编写、打包到注册右键菜单的全部过程,最终得到一个可以日常使用的文件加密解密小工具。

整体思路与实现路径

这个小工具的核心由两部分组成:一个负责加密和解密的Python脚本,以及一组让Windows在右键菜单中显示操作入口的注册表项。右键菜单只是一个"入口",它把选中文件的路径作为参数传递给Python脚本,脚本完成实际的加密或解密工作。

加密算法选择AES-256-CBC模式。AES是目前广泛使用的对称加密标准,256位密钥长度提供了足够的安全性。CBC模式需要一个初始化向量(IV),每次加密随机生成,保证相同文件多次加密后的密文不同。密钥通过用户输入的密码,经PBKDF2算法派生,避免直接使用短密码带来的安全风险。

用Python编写Windows右键菜单小工具:实现文件快速加密与解密
图1:从编写脚本到注册右键菜单的整体流程及加密步骤分解

准备开发环境

开始之前需要确认两件事:系统上安装了Python 3.7或更高版本,以及pip可以正常使用。打开命令提示符,输入以下命令检查:

python --version
pip --version

确认Python可用后,安装加密库pycryptodome。这个库提供了AES加密所需的全部功能:

pip install pycryptodome

如果后续要打包成EXE让没有Python环境的电脑也能使用,还需要安装pyinstaller:

pip install pyinstaller

编写加密解密脚本

脚本需要处理两种操作模式:加密和解密。通过命令行参数区分——运行时传入encrypt或decrypt以及文件路径。密码通过tkinter弹出的简单对话框获取,这样即使从右键菜单启动也能交互输入。

创建一个名为file_crypto.py的文件,完整代码如下:

import sys
import os
import tkinter as tk
from tkinter import simpledialog, messagebox
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad

SALT_SIZE = 16
IV_SIZE = 16
KEY_SIZE = 32
ITERATIONS = 100000

def get_password(title):
    root = tk.Tk()
    root.withdraw()
    password = simpledialog.askstring(title, "请输入密码:", show="*")
    root.destroy()
    if not password:
        sys.exit(0)
    return password.encode("utf-8")

def encrypt_file(filepath):
    password = get_password("文件加密")
    salt = get_random_bytes(SALT_SIZE)
    key = PBKDF2(password, salt, dkLen=KEY_SIZE, count=ITERATIONS)
    iv = get_random_bytes(IV_SIZE)
    cipher = AES.new(key, AES.MODE_CBC, iv)

    with open(filepath, "rb") as f:
        plaintext = f.read()

    ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))
    output_path = filepath + ".enc"

    with open(output_path, "wb") as f:
        f.write(salt + iv + ciphertext)

    root = tk.Tk()
    root.withdraw()
    messagebox.showinfo("完成", f"文件已加密:\n{output_path}")
    root.destroy()

def decrypt_file(filepath):
    password = get_password("文件解密")

    with open(filepath, "rb") as f:
        data = f.read()

    salt = data[:SALT_SIZE]
    iv = data[SALT_SIZE:SALT_SIZE + IV_SIZE]
    ciphertext = data[SALT_SIZE + IV_SIZE:]
    key = PBKDF2(password, salt, dkLen=KEY_SIZE, count=ITERATIONS)
    cipher = AES.new(key, AES.MODE_CBC, iv)

    try:
        plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
    except ValueError:
        root = tk.Tk()
        root.withdraw()
        messagebox.showerror("错误", "密码不正确或文件已损坏。")
        root.destroy()
        sys.exit(1)

    if filepath.endswith(".enc"):
        output_path = filepath[:-4]
    else:
        output_path = filepath + ".dec"

    with open(output_path, "wb") as f:
        f.write(plaintext)

    root = tk.Tk()
    root.withdraw()
    messagebox.showinfo("完成", f"文件已解密:\n{output_path}")
    root.destroy()

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("用法: file_crypto.py [encrypt|decrypt] 文件路径")
        sys.exit(1)

    action = sys.argv[1].lower()
    target = sys.argv[2]

    if not os.path.isfile(target):
        print(f"文件不存在:{target}")
        sys.exit(1)

    if action == "encrypt":
        encrypt_file(target)
    elif action == "decrypt":
        decrypt_file(target)
    else:
        print(f"未知操作:{action}")
        sys.exit(1)

代码要点说明

密钥派生:PBKDF2函数接收用户密码和随机salt,迭代100000次生成32字节(256位)密钥。高迭代次数让暴力破解密码的成本大幅增加。每次加密都使用新的随机salt,因此同一密码对同一文件多次加密会产生不同的密文。

文件格式:加密后的文件依次存储salt(16字节)、IV(16字节)和密文。解密时按固定偏移量分别读取这三部分。这种结构简单可靠,salt和IV本身不需要保密,它们的作用是保证每次加密的唯一性。

错误处理:解密时如果密码错误,unpad函数会因为填充格式不符抛出ValueError异常。脚本捕获这个异常并弹出错误提示,而不是让程序直接崩溃。

在命令行中可以先验证脚本功能:

REM 加密一个测试文件
python file_crypto.py encrypt C:\test\example.txt

REM 解密刚刚生成的加密文件
python file_crypto.py decrypt C:\test\example.txt.enc

运行加密命令后会弹出密码输入框,输入密码并确认后,在同目录下生成example.txt.enc。解密时输入相同密码,会还原出example.txt。

用Python编写Windows右键菜单小工具:实现文件快速加密与解密
图2:加密文件的内部数据结构及解密时的数据还原过程

打包为可执行文件

如果只是自己使用并且电脑上有Python环境,可以跳过打包步骤,直接用python file_crypto.py运行。但要分享给别人或者避免依赖Python环境,需要用PyInstaller打包成EXE。

在脚本所在目录打开命令提示符,执行:

pyinstaller --onefile --noconsole --name file_crypto file_crypto.py

参数说明:--onefile把所有依赖打包进单个EXE文件;--noconsole运行时不弹出命令行窗口(因为交互通过tkinter对话框完成);--name指定输出文件名。打包完成后在dist目录下找到file_crypto.exe。

把这个EXE复制到一个固定位置,比如C:\Tools\file_crypto.exe。后续注册表里会用到这个路径,所以放好之后就不要移动了。

配置Windows右键菜单

Windows的右键菜单项由注册表控制。需要在HKEY_CLASSES_ROOT\*\shell下创建两个子项,分别对应"加密文件"和"解密文件"操作。*表示对所有文件类型生效。

手动编辑注册表

按Win+R输入regedit打开注册表编辑器,导航到HKEY_CLASSES_ROOT\*\shell。

添加"加密文件"菜单项:在shell下新建项,命名为EncryptFile。选中EncryptFile,将右侧"默认"值改为使用密码加密(这是右键菜单中显示的文字)。在EncryptFile下再新建一个名为command的子项,将其默认值设为:

"C:\Tools\file_crypto.exe" encrypt "%1"

%1是Windows传递给命令的文件路径占位符。

添加"解密文件"菜单项:同样在shell下新建DecryptFile项,默认值设为解密文件。在DecryptFile下新建command子项,默认值设为:

"C:\Tools\file_crypto.exe" decrypt "%1"
用Python编写Windows右键菜单小工具:实现文件快速加密与解密
图3:Windows注册表结构及右键菜单项的对应关系

使用注册表脚本快速配置

手动编辑注册表容易出错,更方便的方式是创建一个.reg文件双击导入。新建一个文本文件,保存为add_crypto_menu.reg(注意编码选择UTF-16 LE BOM),内容如下:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\EncryptFile]
@="使用密码加密"
"Icon"="C:\\Tools\\file_crypto.exe,0"

[HKEY_CLASSES_ROOT\*\shell\EncryptFile\command]
@="\"C:\\Tools\\file_crypto.exe\" encrypt \"%1\""

[HKEY_CLASSES_ROOT\*\shell\DecryptFile]
@="解密文件"
"Icon"="C:\\Tools\\file_crypto.exe,0"

[HKEY_CLASSES_ROOT\*\shell\DecryptFile\command]
@="\"C:\\Tools\\file_crypto.exe\" decrypt \"%1\""

双击这个.reg文件,确认导入后右键菜单立即生效。如果需要卸载,创建另一个.reg文件:

Windows Registry Editor Version 5.00

[-HKEY_CLASSES_ROOT\*\shell\EncryptFile]
[-HKEY_CLASSES_ROOT\*\shell\DecryptFile]

项名前的减号-表示删除该注册表项及其所有子项。

注意:修改HKEY_CLASSES_ROOT需要管理员权限。运行.reg文件时如果提示权限不足,右键选择"以管理员身份运行"。如果不想影响所有用户,可以把路径改为HKEY_CURRENT_USER\Software\Classes\*\shell,效果相同但只对当前用户生效。

使用方法与验证

配置完成后,在资源管理器中右键点击任意文件,上下文菜单中会出现"使用密码加密"和"解密文件"两个选项。

加密文件:右键选择"使用密码加密",在弹出的对话框中输入密码。确认后,同目录下生成一个.enc后缀的加密文件。原文件不会被删除或修改。

解密文件:右键点击.enc文件,选择"解密文件",输入加密时使用的密码。解密成功后在同目录生成去掉.enc后缀的文件。如果密码错误,会弹出错误提示。

验证加密效果的简单方法:用文本编辑器打开加密前后的文件。原文件内容正常显示,.enc文件打开后是无法辨认的乱码。解密后的文件应该和原文件完全一致,可以用certutil计算哈希值确认:

certutil -hashfile C:\test\example.txt SHA256
certutil -hashfile C:\test\example.txt.enc.dec SHA256

两个命令输出的SHA256哈希值应该完全相同。

安全性考量与改进方向

这个小工具适合保护日常文件不被随意查看,比如加密个人文档后存到U盘或云盘。但在正式的安全场景中,有几个方面值得注意:

密码强度:AES-256的安全性取决于密码质量。PBKDF2的10万次迭代可以拖慢单次密码试探的速度,但面对过于简单的密码(比如123456)仍然不够。建议使用至少12位、包含大小写字母和数字的密码。

原文件处理:当前脚本在加密后保留了原文件。在对安全性要求较高的场景中,可能需要加密后安全删除原文件。普通的文件删除可以被数据恢复工具还原,彻底删除需要覆写文件内容。可以在加密成功后添加覆写逻辑:

import struct

def secure_delete(filepath, passes=3):
    length = os.path.getsize(filepath)
    with open(filepath, "r+b") as f:
        for _ in range(passes):
            f.seek(0)
            f.write(get_random_bytes(length))
            f.flush()
            os.fsync(f.fileno())
    os.remove(filepath)

大文件处理:当前实现会将整个文件读入内存。处理几百MB甚至更大的文件时可能导致内存不足。改进方法是分块读取和加密,每次处理固定大小(如64KB)的数据块。这需要修改加密逻辑,对最后一个块进行填充,中间块保持原始大小。

密码确认:加密时只要求输入一次密码。实际使用中可以增加二次确认,避免因输入错误导致文件被用错误密码加密而无法恢复。只需在get_password函数中加入确认步骤。

常见问题

右键菜单没有出现:先确认.reg文件是否成功导入——打开注册表编辑器,检查HKEY_CLASSES_ROOT\*\shell下是否存在EncryptFile和DecryptFile项。如果项存在但菜单不显示,尝试重启资源管理器(任务管理器中右键"Windows资源管理器"选择"重新启动"),或注销后重新登录。

点击菜单后没有反应:检查command子项中的EXE路径是否正确、文件是否存在。路径中包含空格时必须用双引号包裹。可以在命令提示符中手动运行完整命令测试:

"C:\Tools\file_crypto.exe" encrypt "C:\test\example.txt"

如果手动运行也报错,可能是打包时缺少依赖,重新运行PyInstaller并检查输出日志。

解密提示密码错误但密码没输错:确认加密文件没有被修改或传输过程中损坏。如果文件通过邮件等方式传输,附件可能被截断。比较原始.enc文件和收到的文件大小是否一致。

用Python编写Windows右键菜单小工具:实现文件快速加密与解密
图4:文件加密解密小工具的完整架构及核心组件总结
相关专题:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表