Я знаю, что это будет очень нишевая тема. Электронная подпись PDF-файлов далека от основного использования. Тем не менее, я напишу это по двум причинам: во-первых, я думаю, что это будет очень полезно для тех немногих, кому это действительно нужно, и, во-вторых, я думаю, что оно будет становиться все более и более распространенным по мере того, как правила eIDAS приобретают популярность, — в основном это говорит что электронные подписи признаются повсюду в Европе (сейчас это не совсем так , из-за некоторых скучных юридических деталей, но в любом случае).
Итак, каков вариант использования — во-первых, вы должны подписать PDF-файл электронной подписью в электронном виде (юридический термин — «электронная подпись», поэтому я буду использовать их взаимозаменяемо, хотя они не полностью совпадают — например, любые электронные данные, примененные к другим данным, могут рассматриваться как электронная подпись, где цифровая подпись является подписью на основе PKI).
Во-вторых, вы можете захотеть отобразить подпись на страницах, вместо того, чтобы программа чтения PDF распознала ее и показала на боковой панели. Почему это? Потому что люди привыкли видеть подписи на страницах, а некоторые могут настаивать на том, чтобы подпись была видимой (правдивая история — у меня есть комментарий, что отдельная подпись «не является НАСТОЯЩЕЙ электронной подписью, потому что ее не видно на странице»).
Теперь обратите внимание, что я написал «страницы» на «странице». Да, у электронного документа нет страниц — это поток байтов. Так что подпись только на последней странице — это нормально. Но, опять же, люди привыкли подписывать все страницы, поэтому они предпочли бы, чтобы электронная подпись была видна на всех страницах.
И это усложняет задачу: PDF удобен тем, что на последней странице есть блок цифровой подписи, но наличие нескольких таких блоков не работает. Поэтому необходимо добавить другие типы аннотаций, которые выглядят как поле для подписи и при щелчке открывают панель для подписи (точно так же, как и поле для подписи).
Я должен представить здесь DSS — замечательный набор компонентов Европейской комиссии, который можно использовать для подписи и проверки всех видов электронных подписей. Это открытый исходный код, вы можете использовать его любым удобным для вас способом. Разверните демонстрационное приложение , используйте только библиотеки, что угодно. Он включает функцию подписи из коробки — просто проверьте PAdESService или PDFBoxSignatureService . Он даже включает возможность визуализировать подпись один раз (на определенной странице).
Тем не менее, он не имеет возможности показывать «штампы» (изображения) на нескольких страницах. Вот почему я его разветвил и реализовал функциональность. Большинство моих изменений в PDFBoxSignatureService в loadAndStampDocument(..)
. Если вы хотите использовать эту функциональность, вы можете просто собрать jar из моего форка и использовать его (передав соответствующие SignatureImageParameters
в PAdESSErvice.sign(..)
чтобы определить, как будет выглядеть подпись).
Зачем это нужно в первую очередь? Потому что, когда документ подписан, вы больше не можете его изменить, так как вы измените хеш. Тем не менее, PDF-файлы имеют постепенные обновления, которые позволяют добавлять к документу и, следовательно, иметь более новую версию, не изменяя ничего в исходной версии. Таким образом, подпись остается действительной (изначально подписанное содержимое не изменяется), но добавляется новый материал. В нашем случае этот новый материал представляет собой некоторые «аннотации», которые представляют изображение и интерактивную область, открывающую панель подписи (по крайней мере, в Adobe Reader). И хотя они добавляются до того, как будет добавлено поле для подписи, если имеется несколько подписывающих, аннотации для второго подписывающего добавляются после первой подписи.
К сожалению, PDFBox не поддерживает это из коробки. Что ж, почти так и есть — фрагмент кода, показанный ниже, выглядит хакерским, и потребовалось некоторое время, чтобы понять, что именно следует вызывать и когда, но он работает только с одним вызовом отражения:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
for (PDPage page : pdDocument.getPages()) { // reset existing annotations (needed in order to have the stamps added) page.setAnnotations( null ); } // reset document outline (needed in order to have the stamps added) pdDocument.getDocumentCatalog().setDocumentOutline( null ); List<PDAnnotation> annotations = addStamps(pdDocument, parameters); setDocumentId(parameters, pdDocument); ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (COSWriter writer = new COSWriter(baos, new RandomAccessBuffer(pdfBytes))) { // force-add the annotations (wouldn't be saved in incremental updates otherwise) annotations.forEach(ann -> addObjectToWrite(writer, ann.getCOSObject())); // technically the same as saveIncremental but with more control writer.write(pdDocument); } pdDocument.close(); pdDocument = PDDocument.load(baos.toByteArray()); ... } private void addObjectToWrite(COSWriter writer, COSDictionary cosObject) { // the COSWriter does not expose the addObjectToWrite method, so we need reflection to add the annotations try { Method method = writer.getClass().getDeclaredMethod( "addObjectToWrite" , COSBase. class ); method.setAccessible( true ); method.invoke(writer, cosObject); } catch (Exception ex) { throw new RuntimeException(ex); } } |
Что он делает — загружает оригинальный PDF, очищает некоторые внутренние каталоги, добавляет аннотации (изображения) на все страницы, а затем «принудительно добавляет аннотации», потому что они «не будут сохранены в инкрементных обновлениях в противном случае». Я надеюсь, что PDFBox сделает это немного проще, но пока это работает, и это не делает недействительными существующие подписи.
Я надеюсь, что этот пост знакомит вас с:
- наличие юридически обязательных электронных подписей
- существование утилит DSS
- стандарт PAdES для подписи PDF
- как разместить более одного поля для подписи в документе PDF
И я надеюсь, что эта статья со временем будет становиться все более популярной, так как все больше и больше компаний осознают, что могут использовать электронные подписи.
Опубликовано на Java Code Geeks с разрешения Божидара Божанова, партнера нашей программы JCG . См. Оригинальную статью здесь: Добавление видимых электронных подписей в PDF-файлы.
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |