Python本身不提供加密文件夹功能,所谓“加密”实为应用层模拟:或加密文件内容后存储,或调用gocryptfs等系统工具实现透明加解密;chmod 0o700仅设访问权限,不加密数据,无法防止root或物理访问者读取明文。

Python 本身不提供“加密文件夹”功能——它没有内置的磁盘级加密或透明文件夹加密能力。所谓“加密文件夹”,实际是应用层模拟:要么对文件内容加密后存入普通文件夹,要么调用系统级工具(如 gocryptfs、encfs)或平台 API(如 Windows EFS、macOS FileVault)间接实现。权限位(如 0o700)仅控制操作系统访问权限,和加密无关,两者不能混为一谈。
为什么 chmod 0o700 不等于加密
设置 os.chmod(path, 0o700) 只是让该目录仅所有者可读写执行,但文件内容仍是明文。任何有 root 权限或物理访问权的人,都能绕过该限制直接读取磁盘数据。它防不住同事、管理员或恶意软件——只防普通用户误操作。
- Linux/macOS 下:
chmod 0o700等价于drwx------,不影响文件内容是否可读 - Windows 下:
os.chmod对权限控制非常有限,主要靠 ACL,0o700基本被忽略 - 加密必须作用于数据字节本身:比如用
Fernet加密每个文件内容,再保存为.enc文件
用 cryptography 库加密单个文件(推荐起点)
最可控、跨平台、无需依赖外部工具的方式,是用 cryptography 对每个文件内容加密后存储。文件夹本身只是容器,不加密;加密逻辑在 Python 层。
- 安装:
pip install cryptography - 密钥必须安全保管:
Fernet.generate_key()返回的bytes需存到独立位置(如硬件密钥、环境变量、受保护配置文件),绝不可硬编码 - 示例核心逻辑:
from cryptography.fernet import Fernet import os <p>key = b'your_32_byte_key_here...' # 必须是 base64 编码的 32 字节 f = Fernet(key)</p><p>def encrypt_file(src, dst): with open(src, 'rb') as f_in: encrypted = f.encrypt(f_in.read()) with open(dst, 'wb') as f_out: f_out.write(encrypted) os.chmod(dst, 0o600) # 加密后设为仅所有者可读写
注意:os.chmod(dst, 0o600) 是附加防护,不是加密本身。
立即学习“Python免费学习笔记(深入)”;
想真正“挂载加密文件夹”?用 gocryptfs(Linux/macOS)
如果需要类 Dropbox 的透明加密体验(打开即解密、保存即加密),gocryptfs 是目前最轻量、审计充分、支持 chmod 透传的方案。Python 可调用它创建/挂载,但加密由其二进制完成。
- 安装:
brew install gocryptfs(macOS)、sudo apt install gocryptfs(Ubuntu) - 初始化加密目录:
gocryptfs -init /path/to/encrypted(会生成gocryptfs.conf和gocryptfs.diriv) - 挂载:
gocryptfs /path/to/encrypted /path/to/mount,之后对/mount的读写自动加解密 - Python 调用示例:
import subprocess subprocess.run(['gocryptfs', '-init', '/tmp/myvault'], input=b'password\npassword\n') # 注意:密码需通过 stdin 传入,不能放命令行参数(会泄露到 ps)
权限位在挂载后可正常设置(os.chmod 作用于挂载点),gocryptfs 会将其映射到底层加密文件属性中。
容易被忽略的关键点
真正落地时,最容易栽在三个地方:密钥生命周期管理、临时文件残留、以及混淆“权限”和“机密性”。比如用 shutil.copy 复制加密文件时,若目标路径未设 0o600,就可能留下可读副本;又比如把密钥写进脚本并 commit 到 Git,等于把锁和钥匙一起贴门上。加密文件夹不是开关按钮,而是一整套数据流约束——从生成、传输、缓存、落盘到销毁,每一步都得检查字节是否始终处于加密态。


















