Обновление существующего PDF для добавления подписи
Мой проект состоит в том, чтобы добавить цифровую подпись в существующий PDF, если Windows, в C++, с поддержкой PAdES. Изучая базовые аспекты формата PDF и вывод jSignPdf, мне удалось успешно подписать любой существующий файл PDF, и Adobe 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
Теперь я создал простой анализатор PDF в C++, и, насколько я понимаю, мне нужно:
- Найти корневой объект (из трейлера)
- Найдите дескриптор страниц из корневого объекта (в данном случае /Pages 2 0 R)
- Найдите первый (?) Дочерний объект из дескриптора страниц (в данном случае /Kids [ 3 0 R ]
- Из объекта, на который есть ссылка, получить содержимое (в данном случае 5)
- Создайте объект obj 9 в моем разделе PDF.
Это всего лишь эксперимент. Что мне нужно, так это какая-то ссылка на PDF-документ, в котором объясняется правильная процедура обращения к предыдущему разделу PDF файла, или какое-либо работающее обновление C++ PDF-add-a-new-document.
Если у меня есть, я посмотрю спецификации PDF и / или источник iText, но я надеюсь, что смогу избежать этого.
Большое спасибо.