标称 AES-256 的 PDF,密钥熵可能只有大约 9 bit
2026年10月27日,安全研究者 Rick de Jager(V12)发文指出:多家 PDF 实现对外宣传 AES-256,真正用来加密正文的文件密钥,却常从过小的状态空间或不安全随机源生成,导致可以不依赖用户密码恢复密钥。
PDF 修订版 6 的流程大致是:实现先生成随机 32 字节文件密钥加密内容,再用口令与盐导出的另一密钥去包裹这份文件密钥。口令哈希被故意做慢,但若文件密钥本身可枚举,整套「升级」就落空。
MuPDF(修复前,文中指 1.28.5 之前)用类似 drand48 的 48 位线性同余发生器,种子是以秒计的 time(NULL)。输出字节只取状态中很窄的一段;高位又不影响低位,再扣掉固定初始化的低 16 位,真正影响 AES-256 密钥的随机态大约只剩 9 bit——相差 512 秒的时间戳会得到同一字节流。作者用穷举约 512 条候选流做试解密,未优化的 Python 实现约 11 毫秒;文档明文里的 /ID 还可当校验。文中给出测试文档在已知条件下恢复出的密钥示例,说明可不输入口令解开。
Foxit(文中版本 2026.1.3.36551)把文件密钥做成「当前时间戳 + 32 字节未初始化缓冲 + 常量 there」的 SHA-256;实践中那 32 字节常被填零,熵几乎只剩时间戳。用 /Perms 块里的已知明文,一次哈希加一块 AES 就能验候选。作者的 Rust 实现在 Ryzen 9 7950X 上约每秒搜索 3.7 亿个时间戳,从「十年前」扫到「现在」往往只要亚秒到数秒。同一模式可追溯到 2014 年公开的 PDFium 初版提交(文件头致谢 Foxit)。
OpenPDF 3.0.5 与 iText 9.7.1 则把密码学随机走到以毫秒时间戳和 JVM 剩余内存拼接串播种的 ARC4 流,同样削弱了「256 bit」承诺。作者称已向厂商披露,MuPDF 侧已修复;已流出的旧文件无法事后补强。文中发布了针对 MuPDF 与 Foxit 的解密工具,供验证与研究。
核心教训简单:算法标签看 AES-256 不够,要问随机数从哪来、状态空间有多大。
来源
[1] The case of the 9 bit AES key,Rick de Jager / V12,2026年10月27日。
[2] Hacker News 讨论,2026年10月29日。
#PDF加密 #AES #随机数 #MuPDF #Foxit
成为第一条评论!
Nobody's responded to this post yet. Add your thoughts and get the conversation going.