最近幾個月幹了不少 PDF 相關的活,趁著這兩天不忙,記錄一下相關的知識點。
PDF是 Portable Document Format的簡稱,翻譯過來是“可攜帶文件格式”,由 Adobe於1992年建立。其格式特點是,與作業系統平臺無關,在任意平臺上都可以保持相同的渲染效果。
至於這個平臺無關嘛……倒不如說是格式簡單,各平臺都遵循同一標準,再加上標準的公開,自然就做到了平臺無關性。
發展史
PDF 從建立之後,一直是 Adobe 公司的專有格式,直到2008年,才成為正式的ISO(ISO 32000)標準。
雖然 PDF 檔案已經成為了標準, 但 Adobe 作為 PDF 的鼻祖,還是弄了些私有的功能,比如 XFA(Adobe PDF 表單),這玩意就不屬於 ISO 32000 PDF標準。
國產格式 - OFD
和 PDF 類似的,還有 OFD (Open 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)頒發的數字證照實現,基本玩法是這樣:
- 對內容使用摘要演算法(如MD/SHA等)生成摘要
- 使用非對稱加密演算法+證照私鑰對摘要進行加密
- 將加密的摘要資料,和簽名的證照(公鑰部分)附在PDF檔案中
從上面的步驟可以看出,PDF 數字簽名和 SSL 加密並不一樣,PDF 本質上是對檔案“簽名”,可以保證檔案簽名者的身份,保證不可篡改,而 SSL 是對報文進行加密。
下圖是非對稱加密演算法下,加密和數字簽名的區別:
總結一下,非對稱加密演算法的主流應用就兩種:公鑰加密 -> 私鑰解密,私鑰加密 -> 公鑰驗籤。
PDF 數字簽名還有個特殊的玩法,可以將數字簽名資訊和圖片進行“繫結”,比如電子發票裡的簽章(Stamp)圖片,這個圖片可以作為數字簽名的外觀(Appearance)。
如果不使用外觀,只進行數字簽名當然也是可以的。不過記住一點:有簽章圖片不一定有數字簽名,有數字簽名也不一定有簽章圖片,這倆不是一個東西。
其實不止是 PDF 檔案才可以數字簽名,微軟家的 Office 套件也是支援數字簽名的,但一般沒人會對 Office 格式的檔案簽名,所以市面上能見到的都是對 PDF 數字簽名。
簽名驗證
PDF 簽名驗證的原理也很簡單:
驗證PDF 的簽名證照是否受信
- 使用客戶端根證照庫(比如Adobe PDF,會使用內建的根證照列表,和作業系統無關),驗證簽名證照是否受信
通過證照的公鑰,對簽名後的摘要資料進行驗籤。
證照 & 簽名演算法
PDF 數字簽名所使用的證照型別,和 SSL 是不一樣的。普通 SSL 的證照驗證域名所有者就可以了,而 PDF 數字簽名所使用的證照一般稱為機構證照,沒有域名的概念,但會嚴格的驗證企業資訊,如營業許可證等等。
目前主流的數字證照非對稱加密演算法有RSA/DSA/DSS,但應用最廣的還是 RSA 演算法,不過隨著國產化的趨勢,金融保險等行業慢慢的遷移到國密演算法了。
不過演算法不重要,都是非對稱加密,都是數字證照,只是具體簽名/驗籤/加密/解密的演算法不同而已。
表單域 - Acro Form
表單域就是指 PDF 表單,英文定義叫 Acro Form。是的你沒看錯,PDF 也有和 HTML 類似的表單技術,表單裡可以配置文字域、單選框、核取方塊等元素:
編輯好了 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 線上工具網站,編輯、轉換等功能都有,相容性也很好,而且每天有一定免費配額
參考
- https://www.wikiwand.com/zh/%E5%8F%AF%E7%A7%BB%E6%A4%8D%E6%96%87%E6%A1%A3%E6%A0%BC%E5%BC%8F
- https://www.ssl.com/zh-CN/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D%E5%92%8C%E6%96%87%E4%BB%B6%E7%AD%BE%E5%90%8D/
- https://www.wosign.com/FAQ/faq_2019070401.htm
- http://gmssl.org/
- https://itextpdf.com/sites/default/files/2018-12/digitalsignatures20130304.pdf