使用Ghostscript压缩PDF时digital signature失效问题如何解决
- 数字签名的生效逻辑是和原始PDF的全量字节哈希绑定的,只要PDF的内容、结构、元数据发生任何修改,哈希校验就会失败,签名直接失效。
- 你所使用的Ghostscript压缩逻辑是调用pdfwrite设备全量重写生成全新PDF,而非在原PDF基础上做增量修改:命令中配置的图像降采样、兼容性等级调整、
-dPrinted=true参数都会修改PDF内部的资源流、页面结构、元数据,相当于完全重构了PDF文件,自然会破坏原签名的校验关系。 - 旧版本Ghostscript没有签名保留逻辑,重写过程会直接丢弃签名相关的对象字典,就算内容没修改也会导致签名丢失。
方案1:先压缩后重签(兼容性最高,100%可用)
步骤如下:- 提前验证原PDF的签名有效性,留存好签名对应的证书、原签名附件等材料
- 执行你现有的压缩命令完成PDF压缩:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dDownsampleColorImages=true -dPrinted=true -dColorImageResolution=100 -dNOPAUSE -dBATCH -sOutputFile=output.pdf input.pdf - 对压缩后的output.pdf重新执行数字签名流程即可。
方案2:调整Ghostscript参数保留原签名(适合可接受压缩率降低、必须保留原签名的场景)
仅支持Ghostscript 9.50及以上版本,修改命令添加-dPreserveSignatures=true参数,同时关闭会大幅修改文档内容的配置,修改后命令如下:gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dDownsampleColorImages=true -dPrinted=false -dColorImageResolution=100 -dPreserveSignatures=true -dNOPAUSE -dBATCH -sOutputFile=output.pdf input.pdf
注意:该方案仅能保留签名对象,如果压缩过程中修改了签名覆盖的文档字节,签名依然会校验失败,成功率和原PDF的签名认证等级、压缩修改幅度有关。方案3:低修改幅度压缩(适合签名允许微小调整的场景)
如果你的PDF签名认证等级允许添加注释、修改元数据等微小操作,可以使用仅压缩冗余资源、不修改内容流的参数,最大程度避免破坏签名,命令如下:gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dCompressFonts=true -dSubsetFonts=true -dDeleteUnusedResources=true -dPreserveSignatures=true -dNOPAUSE -dBATCH -sOutputFile=output.pdf input.pdf
内容的提问来源于stack exchange,提问作者Aarti

