Python加密PDF与解密PDF PyPDF2 方法
用Python+PyPDF2给PDF设置打开密码、解除已有密码,批量加解密,适合合同外发前自动加密。
场景痛点
对外发送合同时经常要给PDF加打开密码,防止泄露;收到带密码的PDF时又要批量解密才能统一处理。手动在Adobe里一份份输入密码另存,效率低还容易忘。用Python脚本可以一键对整个文件夹的PDF批量加密码,或者对已知密码的PDF批量解锁成无密码版本。
用到的库
pip install PyPDF2
完整代码
# -*- coding: utf-8 -*-
"""
PDF 加密与解密
"""
from PyPDF2 import PdfReader, PdfWriter
def encrypt_pdf(src_path: str, out_path: str, user_pwd: str, owner_pwd: str = None) -> None:
"""
给 PDF 加打开密码
:param src_path: 源 PDF 路径
:param out_path: 加密后输出路径
:param user_pwd: 用户打开密码
:param owner_pwd: 所有者密码(可选,权限控制用)
"""
reader = PdfReader(src_path)
writer = PdfWriter()
# 把所有页加进去
for page in reader.pages:
writer.add_page(page)
# encrypt 支持字符串密码,也可以同时设置 owner 密码
if owner_pwd:
writer.encrypt(user_password=user_pwd, owner_password=owner_pwd, use_128bit=True)
else:
writer.encrypt(user_password=user_pwd, use_128bit=True)
with open(out_path, "wb") as f:
writer.write(f)
print(f"已加密 -> {out_path}")
def decrypt_pdf(src_path: str, out_path: str, password: str) -> None:
"""
解除 PDF 密码
:param src_path: 加密 PDF 路径
:param out_path: 解密后无密码 PDF 路径
:param password: 已知的打开密码
"""
reader = PdfReader(src_path)
if not reader.is_encrypted:
print(f"{src_path} 未加密,直接拷贝即可")
else:
# decrypt 返回 0 表示失败,>0 表示成功
if reader.decrypt(password) == 0:
print(f"密码错误: {src_path}")
return
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
with open(out_path, "wb") as f:
writer.write(f)
print(f"已解密 -> {out_path}")
if __name__ == "__main__":
# 加密
encrypt_pdf("原始.pdf", "加密版.pdf", user_pwd="123456")
# 解密
decrypt_pdf("加密版.pdf", "解密版.pdf", password="123456")
代码讲解
- 加密流程:
PdfReader读源文件 →PdfWriter把所有页加进去 →writer.encrypt(...)设置密码 →write()写出。 use_128bit=True使用 128 位 AES 加密,兼容性好;老版本Reader也能打开。owner_password用于权限控制(禁止打印、禁止复制),日常只用user_password即可。- 解密流程:先判断
reader.is_encrypted,如果已加密就decrypt(password),返回值是 0 说明密码不对。 - 解密本质是重新生成一份不带
/Encrypt对象的新PDF,所以结果就是无密码版本。
运行结果
同目录生成 加密版.pdf(打开需要输入 123456)和 解密版.pdf(直接打开无密码)。可以用Adobe或浏览器验证。
注意事项
- PyPDF2 只支持密码保护的加解密,不支持 DRM、证书加密。
- 密码强度自己把控,脚本不会帮你校验强度。
- 加密后书签、表单字段会保留,但部分PDF阅读器对AES256支持不好,建议用
use_128bit=True。 - 批量处理时把函数套进
os.walk()循环即可。

更新时间:2026-09-14 21:40:23
上一篇:Python Excel转PDF:表格不溢出分页打印