0

我的项目是在 Windows 中添加数字签名到现有 PDF,使用 C++,支持 PAdES。通过研究 PDF 格式的基本方面和 jSignPdf 的输出,我成功地签署了任何现有的 PDF 文件,并且 Adob​​e Acrobat 成功找到了 PAdES BT 级签名。

我现在的问题是保留现有的 PDF 信息。据我了解,向现有 PDF 添加额外信息需要:

  • 创建新闻部分 %%EOF、startxref、预告片、外部参照表。
  • 创建一些新对象来描述签名。

jSignPDF(和我的工具)创建了 9 个新对象,其中 8 个是自描述的(即它们引用同一部分的部分:

12 0 obj
<</F 132/Type/Annot/Subtype/Widget/Rect[0 0 0 0]/FT/Sig/DR<<>>/T(Signature1)/V 10 0 R/P 9 0 R/AP<</N 11 0 R>>>>
endobj
10 0 obj
<</Contents<....> 
/Type/Sig/SubFilter/ETSI.CAdES.detached/M(D:20181004191406+00'00')/ByteRange [0 829 60831 1193]/Filter/Adobe.PPKLite>>
endobj
13 0 obj
<</BaseFont/Helvetica/Type/Font/Subtype/Type1/Encoding/WinAnsiEncoding/Name/Helv>>
endobj
14 0 obj
<</BaseFont/ZapfDingbats/Type/Font/Subtype/Type1/Name/ZaDb>>
endobj
11 0 obj
<</Type/XObject/Resources<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/Subtype/Form/BBox[0 0 0 0]/Matrix [1 0 0 1 0 0]/Length 8/FormType 1/Filter/FlateDecode>>stream
...
endstream
endobj
9 0 obj
<</Parent 8 0 R/Contents 5 0 R/Type/Page/Resources<</Font<</Helv 13 0 R>>>>/MediaBox[0 0 200 200]/Annots[12 0 R]>>
endobj
8 0 obj
<</Type/Pages/MediaBox[0 0 200 200]/Count 1/Kids[9 0 R]>>
endobj
7 0 obj
<</Type/Catalog/AcroForm<</Fields[12 0 R]/DR<</Font<</Helv 13 0 R/ZaDb 14 0 R>>>>/DA(/Helv 0 Tf 0 g )/SigFlags 3>>/Pages 8 0 R>>
endobj
15 0 obj
<</Producer(AdES Tools)/ModDate(D:20181002132630+03'00')>>
endobj
xref
7 9
.... 
trailer
<</Root 7 0 R/Prev 492/Info 15 0 R/Size 12>>
startxref
61760
%%EOF

问题是其中的对象 9。

9 0 obj
<</Parent 8 0 R/Contents 5 0 R/Type/Page/Resources<</Font
<</Helv 13 0 R>>>>/MediaBox[0 0 200 200]/Annots[12 0 R]>>

此对象引用原始 PDF 部分。我的问题是,如何创建对它的正确引用。

原始文件是这样的:

%PDF-1.7

1 0 obj  % entry point
<<
  /Type /Catalog
  /Pages 2 0 R
>>
endobj

2 0 obj
<<
  /Type /Pages
  /MediaBox [ 0 0 200 200 ]
  /Count 1
  /Kids [ 3 0 R ]
>>
endobj

3 0 obj
<<
  /Type /Page
  /Parent 2 0 R
  /Resources <<
    /Font <<
      /F1 4 0 R 
    >>
  >>
  /Contents 5 0 R
>>
endobj

4 0 obj
<<
  /Type /Font
  /Subtype /Type1
  /BaseFont /Times-Roman
>>
endobj

5 0 obj  % page content
<<
  /Length 44
>>
stream
BT
70 50 TD
/F1 12 Tf
(Hello, world!) Tj
ET
endstream
endobj

xref
0 6
0000000000 65535 f 
0000000010 00000 n 
0000000079 00000 n 
0000000173 00000 n 
0000000301 00000 n 
0000000380 00000 n 
trailer
<<
  /Size 6
  /Root 1 0 R
>>
startxref
492
%%EOF

现在我用 C++ 创建了一个简单的 PDF 解析器,据我所知,我需要:

  • 找到根对象(来自预告片)
  • 从根对象中查找页面描述符(在本例中为 /Pages 2 0 R)
  • 从页面描述符中找到第一个 (?) 儿童对象(在本例中为 /Kids [ 3 0 R ]
  • 从引用的对象中,获取内容(在本例中为 5)
  • 在我的 PDF 部分构建 obj 9 对象。

不过,这只是实验性的。我需要的是对 PDF 文档的一些参考,它可以解释参考文件的前一个 PDF 部分的正确程序,或者一些有效的 C++ PDF-add-a-new-document 更新。

如果有,我会查看 PDF 规范和/或 iText 源代码,但我希望可以避免这种情况。

非常感谢。

4

0 回答 0