Vic*_*yew 3 pdf-generation openssl cryptography tcpdf php-openssl
我正在使用 TCPDF 生成 pdf 文档并对其进行签名。TCPDF本身只是调用PHP的openssl_pkcs7_sign函数,在我看来这是PKCS7_sign基于源代码调用C的函数。
直到最近,一切都运转良好。然后我改变了证书提供者。我刚刚更新了私钥、证书和证书链:
$pdf->setSignature(
$this->public_certificate_path,
$this->private_key_path,
$this->private_key_password,
$this->extra_certificates_path,
1);
Run Code Online (Sandbox Code Playgroud)
我将 PEM 格式的新根证书和中间证书复制到extra_certificates_path文件内。我使用验证了这个文件openssl,看起来不错。
现在,当我在 Adobe Reader 中打开签名的 PDF 时,它会显示以下错误:
该文件已损坏但正在修复
认证无效
已通过 %s 认证
此签名中包含的格式或信息有错误(支持信息:SigDict /Contents非法数据)
请参阅下面的屏幕截图。
知道可能出了什么问题吗?
分析OP分享的示例文件就可以理解问题所在:嵌入到文档中的签名容器超出了最初为其保留的大小。
因此,解决方案是为签名容器预留更多空间。
事实上,OP 证实:
确实有一个地方指定了最大签名长度。我改变了它,并且有效。
此外,OP 表示他有兴趣如何识别问题。
对于许多 PDF 问题,我们首先使用 PDF 内部浏览器(例如 iText RUPS 或 PDFBox PDFDebugger)检查 PDF。但在这种情况下,文本查看器和十六进制查看器就足够了。
使用文本查看器可以找到签名值字典(此处打印得很漂亮,内容条目已缩短):
10 0 obj
<<
/Type /Sig
/Filter /Adobe.PPKLite
/SubFilter /adbe.pkcs7.detached
/ByteRange[0 78679 90423 6699]
/Contents<308217b7...563934bf>
/Reference [
<<
/Type /SigRef
/TransformMethod /DocMDP
/TransformParams << /Type /TransformParams /P 1 /V /1.2 >>
>> ]
/M (D:20171129170713+00'00')
>>
endobj
Run Code Online (Sandbox Code Playgroud)
ByteRange条目指示Contents值(十六进制编码的签名容器)应从文件偏移 78679 到 90423-1。使用十六进制查看器,可以快速验证内容值 ( ) 的起始索引是否匹配,但结束索引的索引晚于预期。<308217b7...563934bf>
就是这样,嵌入了一个太大的签名容器。;)