什么使Adobe Reader显示"签名"面板?

时间:2017-07-06 13:18:44

标签: php pdf tcpdf

我正在使用PHP签署PDF文件服务器端,我希望Adobe Reader在我生成的PDF上显示此横幅,说该文件已成功签名:

enter image description here

我正在使用 TCPDF库中的代码来实现这一点(我必须修改一些代码以满足我的需求)。 我的工作基于Adobe官方文档中的这两个文档:doc1doc2

我的所作所为:

  1. 将签名标签添加到PDF文件中:

    // 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);
    
  2. 计算并替换 ByteRange

  3. 计算文件的哈希值:

    $hash_result = hash('sha256', $pdfdoc);
    
  4. 使用forge.js对生成的哈希客户端进行签名:我使用我解析的PFX文件,然后使用PFX中包含的数据创建 PKCS7

    < / LI>
  5. 将哈希发送到服务器。

  6. 将签名添加到内容标记中的PDF。
  7. 编辑:感谢@mkl评论我还尝试使用AcroForm将我的Sig对象引用到我的PDF文件中:

    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
    

    它也不起作用。我该如何填写AcroForm字段?

    Adob​​e Reader可以读取生成的PDF,但是没有出现蓝色横幅,为什么?

1 个答案:

答案 0 :(得分:1)

好吧我自己解决了,所以对于那些想知道的人,你需要那些领域:

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

你基本上需要:

  • 1 字体对象(本例中为obj 14)
  • 1 Sig 对象(obj 11)包含&#39;内容中的签名&#39;字段
  • 1 页面对象(对象4)
  • 2 Annot 对象(对象12和13)引用带有 P 标志的第一个页面对象和带有 V 标志的Sig对象
  • 主要目录(obj 1)中的
  • 1 AcroForm 字段引用Fields数组中的2 Annot对象,引用 F1 字段,以及 DocMDP 字段中的签名。

编辑 DocMDP 字段不具有修饰性,只需要一个 Annot 。也不需要字体