Php 是什么让Adobe Reader显示;署名;面板
我正在使用PHP在服务器端对PDF文件进行签名,我希望Adobe Reader在生成的PDF上显示此横幅,说明文件已成功签名: 我正在使用TCPDF库中的代码来实现这一点(我不得不修改一些代码以满足我的需要)。 我的工作基于Adobe官方文档中的这两个文档:和 我所做的:Php 是什么让Adobe Reader显示;署名;面板,php,pdf,tcpdf,Php,Pdf,Tcpdf,我正在使用PHP在服务器端对PDF文件进行签名,我希望Adobe Reader在生成的PDF上显示此横幅,说明文件已成功签名: 我正在使用TCPDF库中的代码来实现这一点(我不得不修改一些代码以满足我的需要)。 我的工作基于Adobe官方文档中的这两个文档:和 我所做的: 将签名标记添加到PDF文件: // The ID of the last object of the PDF + 1 $sigobjid = preg_match_all("/([0-9]+) 0 obj/", $pdfd
// The ID of the last object of the PDF + 1
$sigobjid = preg_match_all("/([0-9]+) 0 obj/", $pdfdoc, $output_array);
$sigobjid = end($output_array[1]) + 1;
// Write the signature tags where needed
$index_to_write = strrpos($pdfdoc,"endobj") + 6;
$signature_tag = PHP_EOL . $sigobjid . ' 0 obj '. PHP_EOL . '<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /adbe.pkcs7.detached '. TCPDF_STATIC::$byterange_string . ' /Contents<'.str_repeat('0', $tcpdf->get_signature_max_length()).'> >>' . PHP_EOL . 'endobj';
$pdfdoc = substr_replace($pdfdoc, $signature_tag, $index_to_write, 0);
11 0 obj
<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /adbe.pkcs7.detached /ByteRange[0 2846 14590 507] /Contents< ...
endobj
12 0 obj
<</AcroForm 11 0 R >>
endobj
// The ID of the last object of the PDF + 1
$sigobjid = preg_match_all("/([0-9]+) 0 obj/", $pdfdoc, $output_array);
$sigobjid = end($output_array[1]) + 1;
// Write the signature tags where needed
$index_to_write = strrpos($pdfdoc,"endobj") + 6;
$signature_tag = PHP_EOL . $sigobjid . ' 0 obj '. PHP_EOL . '<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /adbe.pkcs7.detached '. TCPDF_STATIC::$byterange_string . ' /Contents<'.str_repeat('0', $tcpdf->get_signature_max_length()).'> >>' . PHP_EOL . 'endobj';
$pdfdoc = substr_replace($pdfdoc, $signature_tag, $index_to_write, 0);
11 0 obj
<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /adbe.pkcs7.detached /ByteRange[0 2846 14590 507] /Contents< ...
endobj
12 0 obj
<</AcroForm 11 0 R >>
endobj
110对象
好吧,我自己解决了,所以对于那些想知道的人,你需要这些字段:
1 0 obj
<<
/Type /Catalog /AcroForm << /Fields [12 0 R 13 0 R] /NeedAppearances false /SigFlags 3 /DR << /Font << /F1 14 0 R >> >> /DA (/F1 0 Tf 0 g) /Q 0 >> /Perms << /DocMDP 11 0 R >>
>>
endobj
4 0 obj
<<
/Type /Page
...
endobj
11 0 obj
<< /Type /Sig /Filter /Adobe.PPKLite /SubFilter /adbe.pkcs7.detached /ByteRange[0 3153 14897 922] /Contents<...> /Reference [ << /Type /SigRef /DigestMethod /SHA256 /TransformMethod /DocMDP /TransformParams << /Type /TransformParams /P 2 /V /1.2 >> >> ] >>
endobj
12 0 obj
<< /Type /Annot /Subtype /Widget /Rect [510.236220 572.598661 552.755906 615.118346] /P 4 0 R /F 4 /FT /Sig /T (Signer Name) /Ff 0 >>
endobj
13 0 obj
<< /Type /Annot /Subtype /Widget /Rect [510.236220 572.598661 552.755906 615.118346] /P 4 0 R /F 4 /FT /Sig /T (Signer Name) /Ff 0 /V 11 0 R >>
endobj
14 0 obj
<</Type /Font /Subtype /Type1 /BaseFont /Helvetica /Name /F1 /Encoding /WinAnsiEncoding >>
endobj
10对象
/DA(/F1 0 Tf 0 g)/Q 0>>/Perms>
>>
endobj
40 obj
] >>
endobj
12 0 obj
>
endobj
13 0 obj
>
endobj
140 obj
endobj
你基本上需要:
- 1Font对象(本例中为obj 14)
- 1Sig对象(obj 11),包含“内容”字段中的签名
- 1页面对象(obj 4)
- 2不对象(obj 12和13)引用带有P标志的第一页对象和带有V标志的Sig对象
- 1主目录中的AcroForm字段(obj 1)引用字段数组中的2 Annot对象,在F1字段中引用字体,在DocMDP字段中引用签名
编辑:DocMDP
字段不可修改,只需一个字段即可。也不需要字体 你能分享这个PDF吗?我不是很喜欢PHP,但是你展示的代码似乎只关注于创建一个签名字典。您是否在其他地方也创建了一个签名表单字段(或找到一个空的现有字段),并将您的签名字典指定为它的值?如果您没有,那么这就是(至少部分)问题所在,要让PDF查看器找到签名字典,它必须是PDF AcroForm结构中签名字段的值。@mkl谢谢您的回答!我不知道AcroForm结构,因为文档中很少提到它。我试图添加一个像这样的引用,其中11是我的Sig对象的ID,但它也不起作用,什么也没有出现。你能告诉我AcroForm应该包含什么吗?“我不知道AcroForm结构,因为文档中很少提到它。”-好吧,ISO 32000-1(你称之为“doc1”)的第12.7小节(超过30页)涉及AcroForm表单。请读一下。提示:文档目录中的AcroForm条目应指向交互式表单词典。在这种情况下,您应该正确设置SigFlags,并将字段设置为表单字段的数组,即至少有一个签名字段,其V值是您的签名字典,其T值是字段名,其AP值包含外观。谢谢!我的意思是没有例子,对于一种广泛使用的文件来说,这很奇怪。我不确定这些字段,因为我有我自己签名的PDF文件,显示蓝色横幅,但没有这些字段。