我知道这将是一个非常特殊的话题。 电子签名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相关推荐

  1. 添加Adobe PDF 打印机

    这个虚拟打印驱动叫"Adobe PDF Printer",正常情况下,安装完Adobe Acrobat后,系统就会自动添加Adobe PDF Converter打印机. 如果没有的 ...

  2. 如何快速将图像添加到PDF?

    图片作为PDF的重要组成部分之一,我们经常在编辑PDF文件的时候需要在PDF文件里面添加图片,那如何快速将图像添加到PDF文件中呢?推荐大家使用金闪PDF编辑器,你可以轻松地将图像添加到PDF文档,而 ...

  3. Apache PDFBox 将嵌入文件添加到 PDF 文档

    本教程演示如何将嵌入文件添加到 PDF 文档. Maven 依赖项 我们使用 Apache Maven 来管理我们的项目依赖项.确保以下依赖项驻留在类路径中. <dependency>&l ...

  4. PDF怎么插入页?将页面添加到 PDF 文档的 3 种简单方法

    得益于现代技术,我们现在可以轻松地合并.创建.编辑 PDF 并执行更多操作.使用专业的PDF程序在PDF文档中插入一页问题不大.这篇文章将介绍如何使用 奇客PDF编辑 和其他四个桌面和在线程序向 PD ...

  5. app canvas渲染后图片黑色_H5 基于 canvas 实现电子签名并生成PDF文档

    (给前端大全加星标,提升前端技能) 转自:coyota666 https://juejin.cn/post/6901273585428463624 前言 电子签名通俗来说就是通过技术手段实现在电子文档 ...

  6. pdf php 添加元数据,PDF怎么添加/清除元数据-PDF添加/清除元数据的方法 - 河东软件园...

    PDF是我们最常见的文档格式,而在我们创建一份原创的PDF文档时,为了保护文档的安全以及对文档进行标记,我们常常需要在PDF文档中添加元数据,诸如作者.发布者.主题.标题.创建者等信息,而部分用户可能 ...

  7. linux pdf 加水印,将动态水印添加到PDF

    您使用FPDI与FPDF结合使用的一些信息可以重新创建初始文档 . FPDI的免费版本不支持PDF 1.5中引入的压缩功能 . 无论如何,我们提供了一个商业插件,增加了对此的支持:FPDI PDF-P ...

  8. java pdf stamper_使用pdfstamper(Itext)将页码添加到pdf

    我有这个代码 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws Servle ...

  9. itextsharp php,将页码添加到pdf文档(itextsharp)

    您必须使用iTextSharp打开PDF并自行添加页码.我曾经做过这样的事情,这是我的功能可能会给你一个开始. 该功能将当前页面添加到左下角,因此您可能必须将其放置在符合您需要的其他位置. publi ...

最新文章

  1. 自定义Android菜单背景
  2. JMeter 压力測试使用函数和 CSV 文件參数化 json 数据
  3. 网络安全-windowserver搭建DHCP服务器
  4. HTTP协议基础知识总结
  5. 【个人网盘-updog】使用updog建立个人网盘,so easy
  6. ssl提高组周六模拟赛【2019.3.2】
  7. 【Java】Mybatis mapper动态代理方式
  8. spring中配置quartz定时器
  9. ffmpeg常用数据结构4
  10. 序列化和反序列化的几种方式(JavaScriptSerializer 、XmlSerializer、DataContractSerializer)(一)...
  11. Java实习日记(3)
  12. 教你如何破解无线网络密码(无线网络密码破解)
  13. python连接MongoDB
  14. 飞书从个性到共性,企业微信从共性到个性
  15. android跳过网络连接,绕过Android Android的Wi-Fi热点5设备连接限制 | MOS86
  16. 《微型计算机原理与接口技术》复习笔记(二)
  17. cocos2d-x传智播客_10年和超过520集播客-科技是一场马拉松,而不是短跑
  18. ps抠图教程从入门到高级
  19. 无畏先锋服务器没响应,LOL:为啥不删除“郊区”?无畏先锋人气惨淡,21分钟匹配不到人...
  20. split分割字符串(按两种符号分割)

热门文章

  1. 牛客网暑期ACM多校训练营(第三场)
  2. 4、oracle数据库的查询基础
  3. Java压缩技术(五) GZIP相关——浏览器解析
  4. MyEclipse生成Javadoc帮助文档
  5. Go语言、Docker 和新技术
  6. Hibernate中使用Criteria查询及注解——(HibernateUtil)
  7. JAVASE阶段流程图
  8. 解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)错误
  9. GitLab创建项目 命令上传代码
  10. java正则表达式验证密码_最新密码验证正则表达式