我正在使用TCPDF生成pdf文档并对其进行签名。 TCPDF本身只调用PHP的openssl_pkcs7_sign
函数,在我看来,它基于source code调用C&#39 PKCS7_sign
函数。
直到最近,事情还不错。然后我改变了证书提供者。我刚刚更新了私钥,证书和证书链:
$pdf->setSignature(
$this->public_certificate_path,
$this->private_key_path,
$this->private_key_password,
$this->extra_certificates_path,
1);
我在extra_certificates_path
文件中以PEM格式复制了新的根证书和中间证书。我使用openssl
验证了此文件,看起来很好。
现在,当我在Adobe Reader中打开已签名的PDF时,会显示以下错误:
此文件已损坏但正在修复
认证无效
通过%s认证
此签名中包含的格式或信息存在错误(支持信息:SigDict / Contents非法数据)
见下面的截图。
知道可能出现什么问题吗?
答案 0 :(得分:3)
分析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
ByteRange 条目表示内容值(十六进制编码的签名容器)应从文件偏移量78679到90423-1。使用十六进制查看器可以快速验证内容值(<308217b7...563934bf>
)的起始索引是否匹配,但结束索引的索引是否高于预期。
你有,一个太大的签名容器被嵌入。 ;)