如何确保已签名PDF仅新增签名且内容未篡改?
已签名PDF和参考文档的对比验证思路
你的思路对吗?
大方向没毛病,但不够周全。靠对比增量更新的xref表来确认只加了签名相关对象是核心步骤,但还得结合直接检查增量内容,光看xref表可能漏过一些特殊情况。
有没有可能不改xref表就篡改渲染内容?
不可能。PDF的增量更新规则摆死了:所有新增或改动的对象必须在xref表里登记——要么加新的xref条目,要么改现有条目的偏移量。要改渲染内容,肯定得动页面内容流、资源字典这类对象,这些改动必须体现在xref表,不然PDF阅读器根本读不到修改后的内容。
对比xref表要注意啥?
- 分清新增对象和修改对象:正常签名操作只能加新对象,不能改原有对象(除非是更新根字典里的AcroForm或签名域条目,这属于签名相关的正常操作)
- 查xref表的增量结构:确保增量部分的xref表只指向新增的签名相关对象,以及必要的更新条目(比如根字典的修改)
- 验证对象偏移的合法性:新增对象的偏移必须在参考文档的EOF之后,不能覆盖原有内容
哪些对象属于签名操作的正常范围(白名单)?
这些对象的新增或修改都是签名的正常操作,不算篡改:
- 签名字典(Sig对象)
- 签名域字典(Widget注释的子字典)
- 新增的AcroForm条目(如果之前没表单)或更新后的AcroForm字典
- 根字典(Catalog)的修改(仅限添加/更新AcroForm或签名相关条目时)
- 时间戳相关对象(如果带时间戳)
- 增量更新的xref表本身和对应的trailer条目
关于“用文档哈希对比已签名PDF和未签名PDF”的误区
原问题是:怎么通过文档哈希对比已签名PDF和未签名PDF,确认只加了签名?
最高票答案错就错在觉得能直接比哈希——实际上,已签名PDF是在未签名PDF基础上做增量更新生成的,俩文件的哈希肯定不一样,毕竟多了签名相关的增量内容。正确的做法应该是:
- 把已签名PDF里签名覆盖范围之前的原始内容提出来,算它的哈希
- 验证签名的哈希值和这个原始内容的哈希对不对得上
- 检查增量部分只有签名相关的对象,没改原始内容里的任何对象
这样才能保证签名是针对原始文档生成的,而且原始内容没被篡改。
内容的提问来源于stack exchange,提问作者lvella
相关产品推荐
相关产品推荐

