1

PDF 那些事

 2 years ago
source link: https://segmentfault.com/a/1190000041396802
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

最近几个月干了不少 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.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 在线工具网站,编辑、转换等功能都有,兼容性也很好,而且每天有一定免费配额

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK