Php 是什么让Adobe Reader显示;署名;面板

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

我正在使用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/", $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
    
  • 使用forge.js对生成的哈希客户端进行签名:我使用一个我解析的PFX文件,然后使用PFX中包含的数据创建一个PKCS7

  • 将哈希发送到服务器

  • 将签名添加到内容标签中的PDF中
  • 编辑:多亏了@mkl comment,我还尝试使用AcroForm将我的Sig对象引用到我的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);
    
    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文件,显示蓝色横幅,但没有这些字段。