PDF 那些事

1,781 阅读7分钟

最近几个月干了不少 PDF 相关的活,趁着这两天不忙,记录一下相关的知识点。

PDFPortable Document Format的简称,翻译过来是“可携带文档格式”,由 Adobe于1992年创建。其格式特点是,与操作系统平台无关,在任意平台上都可以保持相同的渲染效果。 ​

至于这个平台无关嘛……倒不如说是格式简单,各平台都遵循同一标准,再加上标准的公开,自然就做到了平台无关性。

发展史

PDF 从创建之后,一直是 Adobe 公司的专有格式,直到2008年,才成为正式的ISO(ISO 32000)标准。 ​

虽然 PDF 文件已经成为了标准, 但 Adobe 作为 PDF 的鼻祖,还是弄了些私有的功能,比如 XFA(Adobe PDF 表单),这玩意就不属于 ISO 32000 PDF标准。

国产格式 - OFD

和 PDF 类似的,还有 OFDOpen Fixed-layout Documents)格式,算是“国产PDF”标准,由中国国家标准化管理委员会于2016年正式发布。

和 PDF 格式相比,OFD 格式更简单,更易于实现,而且支持国密,不过目前使用的很少。

字体

常见的 Office 格式里,字体默认都是非内嵌的,非内嵌字体可以避免重复存储相同的字体,只需要渲染设备上安装对应字体就行;但劣势也很明显,如果客户设备上没有对应的字体,就会导致无法渲染,使用替代字体的话,又会影响渲染效果。 ​

而 PDF 在字体的处理上和 Office 有所不同,PDF 默认使用内嵌字体的方式,而且还是内嵌字体的子集 - 只把文件中使用的字符字体给嵌入到PDF文件中,并不会将整个字体库嵌入。这样一来,即时内嵌了字体,也不会过多的增加文件大小。

字体加密

某些文档为了数据安全,提供 PDF 格式的资料供查阅,但又不想让用户随意复制文字。 ​

此时 PDF 内嵌字体的好处就体现出来了,基于字体混淆 & 加密技术,让当前 PDF 使用混淆 & 加密后的字体库。这样就算公开提供了 PDF 文件,客户复制后的文字也是混淆后的,也算保障了数据安全。 ​

不过现在 OCR 这么强大,混淆字体后,仍然可以通过 OCR 的手段去识别,只是需要多花费一些精力而已。

电子签名 & 数字签名

电子签名 - Electronic Signature

美国 《全球和国家商业电子签名法》 (2000年)将“电子签名”定义为“附在合同上或通过电子方式生成,发送,传达,接收或存储的其他记录或与之逻辑关联的电子声音,符号或过程。”

实际上,电子签名只是将手写签名的图片,附在电子文档上,然后配合一些多因素身份验方式(PIN/密码/邮箱)证来完成。

数字签名 - Digital Signature

数字签名和电子签名不同,数字签名需要配合 PKI 认证中心(CA)颁发的数字证书实现,基本玩法是这样:

  1. 对内容使用摘要算法(如MD/SHA等)生成摘要
  2. 使用非对称加密算法+证书私钥对摘要进行加密
  3. 将加密的摘要数据,和签名的证书(公钥部分)附在PDF文件中

从上面的步骤可以看出,PDF 数字签名和 SSL 加密并不一样,PDF 本质上是对文件“签名”,可以保证文件签名者的身份,保证不可篡改,而 SSL 是对报文进行加密。 ​

下图是对称加密算法下,加密和数字签名的区别: image (1).png 总结一下,非对称加密算法的主流应用就两种:公钥加密 -> 私钥解密,私钥加密 -> 公钥验签。 ​

PDF 数字签名还有个特殊的玩法,可以将数字签名信息和图片进行“绑定”,比如电子发票里的签章(Stamp)图片,这个图片可以作为数字签名的外观(Appearance)。 image.png

如果不使用外观,只进行数字签名当然也是可以的。不过记住一点:有签章图片不一定有数字签名,有数字签名也不一定有签章图片,这俩不是一个东西。 ​

其实不止是 PDF 文件才可以数字签名,微软家的 Office 套件也是支持数字签名的,但一般没人会对 Office 格式的文件签名,所以市面上能见到的都是对 PDF 数字签名。

签名验证

PDF 签名验证的原理也很简单:

  1. 验证PDF 的签名证书是否受信
    1. 使用客户端根证书库(比如Adobe PDF,会使用内置的根证书列表,和操作系统无关),验证签名证书是否受信
  2. 通过证书的公钥,对签名后的摘要数据进行验签。

证书 & 签名算法

PDF 数字签名所使用的证书类型,和 SSL 是不一样的。普通 SSL 的证书验证域名所有者就可以了,而 PDF 数字签名所使用的证书一般称为机构证书,没有域名的概念,但会严格的验证企业信息,如营业许可证等等。 ​

目前主流的数字证书非对称加密算法有RSA/DSA/DSS,但应用最广的还是 RSA 算法,不过随着国产化的趋势,金融保险等行业慢慢的迁移到国密算法了。 ​

不过算法不重要,都是非对称加密,都是数字证书,只是具体签名/验签/加密/解密的算法不同而已。

表单域 - Acro Form

表单域就是指 PDF 表单,英文定义叫 Acro Form。是的你没看错,PDF 也有和 HTML 类似的表单技术,表单里可以配置文本域、单选框、复选框等元素: image.png 编辑好了 PDF 表单之后,就可以通过工具或程序,对PDF进行填充或者填写了。

PDF 库(JAVA)

PDF 技术还是比较封闭的,开源库用起来会非常不爽,如果企业商用的话,尽量还是考虑买商业 SDK,功能丰富,文档完善,花钱买时间。

开源 & 免费

  • Itext - 4.x 版本以下免费,5以上的版本开源许可为AGPL,商用需要付费
  • Openpdf - 基于 itext 2.x 版本修复,还是Itext
  • pdfbox - Apache 下开源的 PDF 库,虽然免费,但功能远不如 Itext,不推荐使用。

还有一些更小众的PDF库,这里就不推荐了。目前使用最多的是 itext,pdfbox 虽然完全开源免费,但功能和文档丰富程度远不及 itext。

商业

  • Itext 7 - 有 JAVA 和 C# 两个版本,功能全,文档完善,基本能满足你对PDF的所有要求。
  • Aspose.PDF - 提供了多语言的 SDK,功能强大,文档也比较丰富
  • Spire.PDF - 提供了多语言的 SDK,功能强大,文档也比较丰富,而且不只是PDF,还支持Office全家桶,在国内也有经销商
  • Adobe PDF Library SDK - Adobe 自家的 PDF SDK,功能肯定是最全的,支持多语言
  • Datalogics PDF Java Toolkit - Datalogics 是 Adobe PDF Library 的代理商,同时自己也提供了另一个版本的 PDF SDK

PDF 工具

PDF 工具市面上一大堆,下面列出一些主流的功能完善的 GUI 工具(阅读、编辑、转换、签名):

  • Adobe Acrobat- PDF 的鼻祖,最强 PDF 工具,没有之一
  • 福昕 - 国产老牌 PDF 软件
  • 万兴PDF
  • 迅捷办公
  • small pdf - 良心的 PDF 在线工具网站,编辑、转换等功能都有,兼容性也很好,而且每天有一定免费配额

参考