我需要了解PDF是否有任何数字签名。我必须管理巨大的 PDF,例如每个500MB,所以我只需要找到一种方法将非签名与签名分开(因此我可以将签名的PDF发送到管理它们的方法)。迄今为止发现的任何程序都涉及尝试通过例如Bouncycastle库(在我的例子中,对于Java):如果存在,则pdf被签名,如果它不存在或引发异常,则不是(原文如此!)。但这显然是时间/内存消耗,而不是资源浪费实现的一个例子。
是否有任何与语言无关的快速方式,例如:打开PDF文件,读取第一个字节并查找告知文件已签名的信息? 或者,是否有任何参考手册详细说明如何在内部制作PDF?
提前谢谢
答案 0 :(得分:5)
您将要使用PDF库,而不是尝试自己实现这一点,否则您将陷入困境,处理线性化文档,过滤器,增量更新,对象流,交叉引用流和更多。
关于参考资料;根据我粗略的搜索,看起来Adobe不再向任何人提供ISO 32000:2008规范的版本,尽管该规范主要是PDF v1.7 Reference manual到ISO符合语言的翻译。
因此,假设PDF v1.7参考,最相关的部分将是8.7(数字签名),3.6.1(文档目录)和8.6(交互式表格)。
基本过程将是:
使用可以使用文档的交叉引用表导航到正确的间接对象的PDF库应该比证书文档的强力搜索更快,资源更少。
答案 1 :(得分:2)
使用命令行,您可以使用 poppler-utils 包中的 pdfsig 工具检查文件是否具有数字签名(适用于 Ubuntu 20.04)。
pdfsig pdffile.pdf
将生成包含签名和验证数据的详细数据的输出。如果您需要扫描 pdf 文件树并获取已签名的 pdf 列表,您可以使用如下 bash 命令:
find ./path/to/files -iname '*.pdf' \
-exec bash -c 'pdfsig "$0"; \
if [[ $? -eq 0 ]]; then \
echo "$0" >> signed-files.txt; fi' {} \;
您将在本地目录中的 signed-files.txt 文件中获得签名文件列表。
我发现这比尝试从 pdf 文件中提取一些文本要可靠得多(例如,立陶宛签名服务生成的 pdf 不包含前面答案中提到的字符串“SigFlags” ).
答案 2 :(得分:1)
这不是最佳解决方案,但它是另一个......你可以检查" Sigflags"并在第一场比赛停止:
grep -m1 "/Sigflags" ${PDF_FILE}
或在目录中获取此类文件:
grep -r --include=*.pdf -m1 -l "/Sigflags" . > signed_pdfs.txt
grep -r --include=*.pdf -m1 -L "/Sigflags" . > non_signed_pdfs.txt
对于大文件,Grep可以非常快。您可以在批处理中运行一段时间并在此之后处理生成的列表(.txt文件)。
请注意,签名后可以逐步修改文件,并且可能不会签署最后一个版本。这将是"签署"
的实际含义无论如何,如果文件没有 / Sigflags 字符串,几乎可以肯定它从未被签名。
请注意,符合标准的读者会开始向后读取(从文件的末尾开始),因为交叉引用表会说明每个对象的位置。
我建议您使用peepdf来检查文件的内部结构。它支持在文件上执行命令。例如:
$ peepdf -C "search /SigFlags" signed.pdf
[6]
$ peepdf -C "search /SigFlags" non-signed.pdf
Not found!!
但我没有测试过它的表现。您可以使用它来浏览PDF的内部结构,并从PDF v1.7 Reference中学习。在那里检查附件和PDF示例。