将可见的电子签名添加到PDF
我知道這將是一個非常特殊的話題。 電子簽名PDF遠不是主流用例。 但是,我將其編寫的原因有兩個:第一,我認為它對真正需要它的人非常有用;第二,我認為隨著eIDAS法規的普及,它將變得越來越普遍。電子簽名在歐洲各地都得到認可(由于某些無聊的法律細節,現在還不完全正確 ,但無論如何)。
因此,用例是什么-首先,您必須使用數字簽名對PDF進行電子簽名(法律術語為“電子簽名”,因此盡管它們不完全匹配,但我將互換使用它們-例如,任何電子應用于其他數據的數據可以看作是電子簽名,其中數字簽名是基于PKI的簽名)。
其次,您可能希望在頁面上實際顯示簽名,而不是讓PDF閱讀器識別簽名并將其顯示在側面板上。 這是為什么? 因為人們習慣于在頁面上看到簽名,有些人可能堅持要使簽名可見(真實的故事–我評論說,分離的簽名“不是真正的電子簽名,因為在頁面上不可見”)。
現在,請注意我在“頁面”上寫了“頁面”。 是的,電子文檔沒有頁面-它是字節流。 因此,僅在最后一頁上簽名即可。 但是,人們還是習慣于對所有頁面進行簽名,因此他們希望電子簽名在所有頁面上都可見。
這使任務變得棘手– PDF可以在最后一頁上有一個數字簽名框,但效果很好。 因此,必須添加看起來像簽名框的其他類型的批注,然后單擊以打開簽名面板(就像實際的簽名框一樣)。
我必須在這里介紹DSS-歐盟委員會提供的一組很棒的組件 ,可用于簽名和驗證各種電子簽名。 它是開源的,您可以隨意使用。 部署演示應用程序 ,僅使用庫。 它包括開箱即用的簽名功能-只需檢查PAdESService或PDFBoxSignatureService即可 。 它甚至還包括一次可視化簽名的選項(在特定頁面上)。
但是,它沒有選擇在多個頁面上顯示“圖章”(圖像)的選項。 這就是為什么我分叉并實現功能的原因。 我的大部分更改都在loadAndStampDocument(..)方法的PDFBoxSignatureService中。 如果要使用該功能,則可以從我的叉子中構建一個jar并將其使用(通過將適當的SignatureImageParameters傳遞給PAdESSErvice.sign(..)來定義簽名的外觀)。
為什么首先需要這樣做? 因為當文檔簽名后,您將無法再對其進行修改,因為您將更改哈希。 但是,PDF具有增量更新,可以將其追加到文檔中,從而具有較新的版本,而無需修改原始版本中的任何內容。 這樣,簽名仍然有效(原始簽名的內容不會被修改),但是會添加新內容。 在我們的案例中,這些新內容是一些“注釋”,它們表示圖像和可打開區域,可打開簽名面板(至少在Adobe Reader中)。 并且在添加簽名框之前添加它們時,如果簽名者不止一個,則第二個簽名者的注釋將在第一個簽名之后添加。
可悲的是,PDFBox不支持該功能。 好吧,它幾乎可以做到–下面的代碼看起來很笨拙,花了一段時間才弄清楚應該確切地調用什么以及何時調用,但是僅需一個反射調用即可工作:
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 controlwriter.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 annotationstry {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實用程序的存在
- 用于PDF簽名的PAdES標準
- 如何在PDF文檔中放置多個簽名框
我希望隨著時間的推移,這篇文章會越來越流行,因為越來越多的企業意識到他們可以使用電子簽名。
翻譯自: https://www.javacodegeeks.com/2018/02/adding-visible-electronic-signatures-pdfs.html
總結
以上是生活随笔為你收集整理的将可见的电子签名添加到PDF的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 笔记本电脑下面菜单栏怎么还原(笔记本工具
- 下一篇: 路由器如何重新设置密码(小米路由器如何重