使用 PHP 的 openssl_pkcs7_sign 签署 pdf 时出错
Error signing pdf with PHP's openssl_pkcs7_sign
我正在使用 TCPDF 生成 pdf 文档并对其进行签名。 TCPDF 本身只是调用 PHP 的 openssl_pkcs7_sign
函数,在我看来它是在调用基于 source code.
的 C 的 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 时,它会显示这些错误:
- 打开文件时,它说
This file is damaged but is being repaired
- 上面的蓝丝带说
Certification by is invalid
- 当我打开签名面板时,它说
Certified by %s
- 详细错误说
There are errors in the formatting or information contained in this signature (support information: SigDict /Contents illegal data)
- 当我点击 "Certificate details" 时,没有任何反应
请参阅下面的屏幕截图。
知道哪里出了问题吗?
分析OP共享的示例文件可以理解问题所在:文档中嵌入的签名容器超出了最初为其保留的大小。
因此,解决方案是为签名容器预留更多space。
事实上,OP 确认:
Indeed there was a place that specified the max signature length. I changed it, and it works.
此外,OP 表示他对如何识别问题感兴趣。
对于许多 PDF 问题,首先要使用 PDF 内部浏览器(如 iText RUPS 或 PDFBox PDFDebugger)检查 PDF。不过,在这种情况下,文本查看器和十六进制查看器就足够了。
使用文本查看器找到签名值字典(此处印刷精美,缩短了 Contents 条目):
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 条目表示 Contents 值(十六进制编码的签名容器)应该从文件偏移量 78679 到 90423-1 .使用十六进制查看器可以快速验证 Contents 值 (<308217b7...563934bf>
) 的起始索引是否匹配,但结束索引位于比预期更晚的索引处。
你看,嵌入了一个太大的签名容器。 ;)
我正在使用 TCPDF 生成 pdf 文档并对其进行签名。 TCPDF 本身只是调用 PHP 的 openssl_pkcs7_sign
函数,在我看来它是在调用基于 source code.
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 时,它会显示这些错误:
- 打开文件时,它说
This file is damaged but is being repaired
- 上面的蓝丝带说
Certification by is invalid
- 当我打开签名面板时,它说
Certified by %s
- 详细错误说
There are errors in the formatting or information contained in this signature (support information: SigDict /Contents illegal data)
- 当我点击 "Certificate details" 时,没有任何反应
请参阅下面的屏幕截图。
知道哪里出了问题吗?
分析OP共享的示例文件可以理解问题所在:文档中嵌入的签名容器超出了最初为其保留的大小。
因此,解决方案是为签名容器预留更多space。
事实上,OP 确认:
Indeed there was a place that specified the max signature length. I changed it, and it works.
此外,OP 表示他对如何识别问题感兴趣。
对于许多 PDF 问题,首先要使用 PDF 内部浏览器(如 iText RUPS 或 PDFBox PDFDebugger)检查 PDF。不过,在这种情况下,文本查看器和十六进制查看器就足够了。
使用文本查看器找到签名值字典(此处印刷精美,缩短了 Contents 条目):
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 条目表示 Contents 值(十六进制编码的签名容器)应该从文件偏移量 78679 到 90423-1 .使用十六进制查看器可以快速验证 Contents 值 (<308217b7...563934bf>
) 的起始索引是否匹配,但结束索引位于比预期更晚的索引处。
你看,嵌入了一个太大的签名容器。 ;)