PDF 加密比其他文件格式更「诡异」——它有用户密码和所有者密码两套机制,安全性差异巨大。上周遇到一个案例:一份加密的 PDF 合同,打不开也打印不了,折腾了一下午终于搞定了。这篇文章把 PDF 密码恢复的技术细节彻底讲清楚。

PDF 加密的两种密码#

PDF 的加密机制和其他文件格式最大的不同在于:它有两种独立的密码

用户密码(User Password / Open Password):
  作用:打开文件时必须输入
  效果:文件内容被加密,没有密码无法查看
  恢复难度:取决于加密算法版本
  这是真正意义上的「加密」

所有者密码(Owner Password / Permissions Password):
  作用:限制打印、复制、编辑等操作
  效果:文件可以打开查看,但不能执行受限操作
  恢复难度:★☆☆☆☆(几乎可以秒解)
  这不是真正的加密,只是一个「限制标记」

如何判断你的 PDF 是哪种密码?#

场景 1:打开 PDF 时弹出密码输入框
  → 用户密码(需要正经恢复)

场景 2:可以打开查看,但打印按钮灰色/复制文字失败
  → 所有者密码(可以轻松移除)

场景 3:既需要密码打开,又有操作限制
  → 两种密码都设置了(先恢复用户密码,再移除所有者密码)

所有者密码:秒解方案#

所有者密码不加密文件内容,只是在 PDF 元数据中设置了一个权限标记。有密码可以修改权限,没密码也可以直接移除。

方法 1:Ghostscript(命令行,免费)#

# 安装 Ghostscript
# macOS: brew install ghostscript
# Ubuntu: sudo apt install ghostscript

# 移除所有者密码(重新生成 PDF)
gs -q -dNOPAUSE -dBATCH \
   -sDEVICE=pdfwrite \
   -dCompatibilityLevel=1.4 \
   -sOutputFile=unlocked.pdf \
   encrypted.pdf

# 原理:Ghostscript 读取 PDF 内容后重新生成一个新的 PDF
# 新 PDF 不包含任何权限限制

方法 2:qpdf(命令行,免费)#

# 安装 qpdf
# macOS: brew install qpdf
# Ubuntu: sudo apt install qpdf

# 移除所有加密
qpdf --decrypt encrypted.pdf unlocked.pdf

# 如果同时有用户密码,需要提供密码
qpdf --password=yourpassword --decrypt encrypted.pdf unlocked.pdf

方法 3:在线工具#

各种在线 PDF 工具(如 ilovepdf.com、smallpdf.com)都可以一键移除所有者密码限制。原理和 Ghostscript 一样——读取内容后重新生成。

注意:
  在线工具需要上传文件到第三方服务器
  如果 PDF 包含敏感信息,建议使用本地工具(Ghostscript / qpdf)

用户密码:正经恢复方案#

用户密码才是真正的加密。PDF 的用户密码加密经历了多个版本的演进:

PDF 加密版本演进:

Revision 2(PDF 1.1-1.3, Acrobat 2-4):
  算法:RC4,40-bit 密钥
  安全性:极弱
  恢复速度:GPU 上数百万次/秒
  恢复难度:★☆☆☆☆

Revision 3(PDF 1.4, Acrobat 5):
  算法:RC4,128-bit 密钥
  安全性:弱(实现有缺陷)
  恢复速度:GPU 上数十万次/秒
  恢复难度:★★☆☆☆

Revision 4(PDF 1.5-1.7, Acrobat 6-8):
  算法:AES-128
  安全性:中等
  恢复速度:GPU 上数万次/秒
  恢复难度:★★★☆☆

Revision 5/6(PDF 2.0, Acrobat X+):
  算法:AES-256
  安全性:强
  恢复速度:GPU 上数千次/秒
  恢复难度:★★★★☆

查看 PDF 加密版本#

# 使用 qpdf 查看加密信息
qpdf --show-encryption encrypted.pdf

# 输出示例:
# R = 6 (AES-256)
# P = -44 (permissions)
# User password = 
# Owner password = set

恢复方案#

方案 1:pdfcpu + Hashcat(技术人员首选)

# 1. 提取 PDF 哈希
# 使用 pdf2john(John the Ripper 附带工具)
python pdf2john.py encrypted.pdf > hash.txt

# 2. 使用 Hashcat 恢复
# PDF 1.1-1.3: -m 10400
# PDF 1.4-1.6: -m 10500  
# PDF 1.7 (AES-128): -m 10600
# PDF 1.7 (AES-256): -m 10700

hashcat -m 10700 hash.txt wordlist.txt -r rules/best64.rule

方案 2:pikepdf(Python,适合自动化)

import pikepdf

# 尝试密码列表
passwords = ['password123', 'admin', '2024', ...]

for pwd in passwords:
    try:
        pdf = pikepdf.open('encrypted.pdf', password=pwd)
        # 密码正确!保存解密版本
        pdf.save('decrypted.pdf')
        print(f"密码找到: {pwd}")
        break
    except pikepdf.PasswordError:
        continue

方案 3:云端恢复服务

如果你不想配置 Hashcat 环境,或者本地 GPU 性能不足,猫密网 支持 PDF 文件的密码恢复。

PDF 恢复的一个优势是:PDF 文件通常比压缩包和 Office 文档小,上传速度更快。猫密网支持 PDF 的多种加密版本(Revision 2-6),对于常见的 4-8 位密码恢复成功率较高。

PDF 恢复的实用建议:

1. 先确认加密版本(用 qpdf --show-encryption)
   - R2/R3 → 本地 Hashcat 几分钟就能搞定
   - R4 → 取决于密码复杂度,本地可能需要几小时
   - R5/R6 → 建议使用云端算力或准备长时间运行

2. 利用 PDF 元数据构建定制字典
   - PDF 的作者名、创建日期、标题都可以作为字典线索
   - 用 pdfinfo 命令查看元数据:
     pdfinfo encrypted.pdf

3. 如果只需要提取文本(不需要保留格式)
   - 某些 PDF 加密只保护编辑权限,不保护文本提取
   - 可以用 pdftotext 直接提取文本内容

实战:恢复一份加密的 PDF 合同#

场景:
  文件:contract_2024.pdf
  问题:打不开(设置了用户密码)
  加密版本:Revision 6 (AES-256)
  线索:完全不记得密码了

恢复过程:

1. 查看加密信息
   $ qpdf --show-encryption contract_2024.pdf
   → R = 6, AES-256

2. 提取哈希
   $ python pdf2john.py contract_2024.pdf > hash.txt

3. 第一轮:常见弱口令字典(rockyou.txt)
   $ hashcat -m 10700 hash.txt rockyou.txt
   → 未命中

4. 第二轮:定制字典
   根据文件名和上下文构建字典:
   - contract, Contract2024, contract@2024
   - signing, Agreement, legal2024
   - ... 约 2000 个候选
   → 未命中

5. 第三轮:规则变异
   $ hashcat -m 10700 hash.txt custom_dict.txt -r rules/best64.rule
   → 2 小时后命中:Signing@2024!

6. 解密
   $ qpdf --password='Signing@2024!' --decrypt contract_2024.pdf decrypted.pdf

总耗时:约 3 小时(含字典构建时间)

PDF 加密的已知弱点#

虽然 Revision 5/6 的 AES-256 加密本身是安全的,但 PDF 格式在实现上有一些已知弱点:

1. Revision 3 的实现缺陷
   RC4-128 的密钥派生过程存在漏洞
   可以将 128-bit 的有效密钥空间降低到约 40-bit
   工具:pdfcrack 可以利用此漏洞加速恢复

2. 元数据泄露
   即使文件被加密,PDF 的元数据(作者、创建日期、修改历史)
   可能以明文形式存在
   这些元数据可以为密码猜测提供线索

3. 增量更新攻击
   PDF 支持增量更新(在文件末尾追加修改)
   某些 PDF 阅读器在处理增量更新时可能绕过加密
   工具:qpdf --linearize 可以检测此问题

各方案对比#

┌────────────────┬────────┬──────────┬──────────────┬──────────────┐
│ 方案            │ 成本   │ 技术门槛  │ 适用加密版本  │ 速度          │
├────────────────┼────────┼──────────┼──────────────┼──────────────┤
│ Ghostscript    │ 免费   │ 中       │ 仅所有者密码  │ 秒级          │
│ qpdf           │ 免费   │ 中       │ 仅所有者密码  │ 秒级          │
│ pikepdf        │ 免费   │ 中       │ R2-R6        │ 慢(CPU)     │
│ Hashcat        │ 免费   │ 高       │ R2-R6        │ 快(GPU)     │
│ 猫密网          │ 免费起  │ 低       │ R2-R6        │ 取决于队列    │
│ Passware Kit   │ $995+  │ 中       │ R2-R6        │ 快(GPU)     │
└────────────────┴────────┴──────────┴──────────────┴──────────────┘

PDF 安全最佳实践#

1. 使用 AES-256 加密(Revision 5/6)
   避免使用旧版 RC4 加密
   在 Adobe Acrobat 中:文件 → 属性 → 安全性 → 选择 "AES-256"

2. 密码强度要求
   至少 12 位,包含大小写字母、数字、特殊字符
   避免使用可预测的模式(生日、公司名等)

3. 使用证书加密作为补充
   PDF 支持证书加密(Certificate Encryption)
   可以用公钥加密 PDF,只有持有私钥的人才能打开
   比密码加密更安全,适合正式的法律文件

4. 考虑数字签名
   如果目的是防篡改而非防查看
   使用数字签名(Digital Signature)比加密更合适
   签名可以验证文件的完整性和来源

结语#

PDF 密码恢复的关键在于先搞清楚你面对的是哪种密码。所有者密码形同虚设,几分钟就能解除;用户密码的恢复难度则取决于加密版本——旧版 RC4 几乎可以秒破,而新版 AES-256 需要好的字典和充足的算力。

对于技术人员,Hashcat 是最强大的免费选择。对于不想折腾环境配置的用户,猫密网等在线服务提供了便捷的替代方案。

无论如何,在加密文件之前,请先把密码存入密码管理器。这是我作为一个经常忘记自己密码的架构师,最真诚的建议。