在不打开 pdf 文件的情况下检查密码

Check password on a pdf file without opening

我正在尝试使用暴力攻击方法来查找 pdf 文件的密码。我使用此方法使用 itextsharp

检查密码
public static bool IsPasswordValid(string pdfFullname, byte[] password) {
    try {
        PdfReader pdfReader = new PdfReader(pdfFullname, password);
        return true;
    } catch (BadPasswordException) {
        return false;
    }
}

有效。但是当 PDF 文件很大时需要很长时间。有没有办法不把文件加载到内存就可以检查密码?

几件事。

首先,在我的 blog post here 中,我发现使用需要 RandomAccessFileOrArray 的构造函数重载是最快的。我刚刚用我手头的源代码 (5.5.6.0) 再次测试,它仍然是基于字符串的路径方法(对于大文件)的两倍快。但是,该构造函数重载被标记为 obsolete,并且实际上可能在更新的版本中被删除,因此您需要 deal/live。

PdfReader pdfReader = new PdfReader(new RandomAccessFileOrArray(pdfFullname, true), password);

非常清楚,出于某种原因专门删除了重载,因此您可能要考虑不使用它。

其次,Is there a way check password without loading file to memory?这个问题实际上是误导。如果内存实际上是瓶颈,你就会遇到更大的问题。我刚刚在一个 80MB 的文件上使用 System.IO.File.ReadAllBytes() 进行了快速测试,将所有内容加载到内存中花费了大约 90 毫秒,而我的计算机已有七年历史了。

实际的速度问题是 iText 需要找到 PDF 的 trailer,它有一个指向 /Encrypt 字典的指针。因为 iText 旨在用于实际 PDF 的某些事情,所以它不会花费大量时间来优化这条路径,因为无论如何它最终都必须发生。如果您真的非常关心速度,这就是我要开始的地方。我建议查看 Adobe's spec to see how the standard PDF encryption works, it's relatively simple. There's also a great simplified description here.

如果你的目标是破解,你应该能够编写一个非常粗略的密码猜测器来查找预告片,查找并找到 /Encrypt 密钥并处理 /O/U 键。如果您还没有阅读规范,其中有很多 "gotchas",例如文档可以有多个 trailer 条目,还有密码的替代方法等。但这可能会让您获得 99% 的常见 PDF在那里。