Python實(shí)現(xiàn)為PDF文檔添加標(biāo)準(zhǔn)數(shù)字簽名
在企業(yè)數(shù)字化轉(zhuǎn)型的當(dāng)下,在線(xiàn)簽署合同和電子發(fā)票加蓋公章等已經(jīng)成為無(wú)紙化辦公的日常。電子簽名和數(shù)字簽名也越來(lái)越頻繁地出現(xiàn)在日常交流和文件簽發(fā)中。
它們聽(tīng)起來(lái)相似,但卻有著極大的區(qū)別。如果你正在開(kāi)發(fā)一個(gè)合同管理系統(tǒng)、辦公自動(dòng)化(OA)系統(tǒng)或開(kāi)票系統(tǒng),混淆這兩個(gè)概念可能會(huì)帶來(lái)致命的合規(guī)性漏洞或安全隱患。本文將帶你從定義、底層技術(shù)、法律效力等維度深度對(duì)比這兩者,并展示如何使用 Python 快速在文件中插入標(biāo)準(zhǔn)的 PDF 數(shù)字簽名。
一、 數(shù)字簽名和電子簽名是一回事嗎?
簡(jiǎn)單來(lái)說(shuō),數(shù)字簽名是一個(gè)技術(shù)和密碼學(xué)層面的概念,而電子簽名則是一個(gè)法律和業(yè)務(wù)層面的概念。數(shù)字簽名其實(shí)是電子簽名的一種特定、高級(jí)且最具安全保障的技術(shù)實(shí)現(xiàn)形式。

1. 什么是數(shù)字簽名?
數(shù)字簽名是基于非對(duì)稱(chēng)加密算法和數(shù)字證書(shū)的技術(shù)方案,旨在解決網(wǎng)絡(luò)世界中的信任與防篡改問(wèn)題。它的密碼學(xué)原理如下:
- 簽署階段:系統(tǒng)計(jì)算待簽署文件的數(shù)字摘要(如 SHA-256 哈希值),然后用簽署人獨(dú)有的私鑰對(duì)這個(gè)摘要進(jìn)行加密,生成一段密文。這段密文就是數(shù)字簽名,它會(huì)被嵌入到 PDF 等文件結(jié)構(gòu)中。
- 驗(yàn)證階段:接收方(或 PDF 閱讀器)使用簽署人的公鑰解密該簽名得到原始摘要,同時(shí)對(duì)接收到的文件重新計(jì)算一次哈希值。如果兩個(gè)摘要完全一致,則證明文件確實(shí)由私鑰擁有者簽署,且中途沒(méi)有被任何第三方篡改,從而保證文件的真實(shí)性和完整性。
2. 什么是電子簽名?
相比之下,電子簽名的范疇要廣得多。依據(jù)我國(guó)《電子簽名法》,電子簽名是指“數(shù)據(jù)電文中以電子形式所含、所附用于識(shí)別簽名人身份并表明簽名人認(rèn)可其中內(nèi)容的數(shù)據(jù)”。
通俗來(lái)講,只要是能證明某人同意了某項(xiàng)內(nèi)容的電子痕跡,在法律和業(yè)務(wù)層面上都可以算作電子簽名。例如:
- 網(wǎng)頁(yè)上彈出的服務(wù)協(xié)議,你勾選了“我已閱讀并同意”;
- 協(xié)同辦公軟件里,你用鼠標(biāo)繪制的、略顯歪扭的手寫(xiě)簽名圖片;
- 甚至是你回復(fù)的一封主題為“我同意該方案”的電子郵件。
二、 數(shù)字簽名 vs 電子簽名多維度對(duì)比表格
為了更直觀地理解,我們從以下五個(gè)核心維度對(duì)兩者進(jìn)行全面對(duì)比:
| 對(duì)比維度 | 數(shù)字簽名 (Digital Signature) | 電子簽名 (Electronic Signature) |
|---|---|---|
| 技術(shù)本質(zhì) | 密碼學(xué)應(yīng)用(非對(duì)稱(chēng)加密、哈希算法) | 廣義的電子標(biāo)記/符號(hào)(無(wú)特定技術(shù)限制) |
| 核心目的 | 證明文件的完整性與簽署人的真實(shí)性 | 證明簽署人的意愿(表明“我認(rèn)可”) |
| 防篡改能力 | 高。任何微小的改動(dòng)都會(huì)破壞哈希值,導(dǎo)致簽名立即失效 | 無(wú)。單純的圖片疊加或前端日志無(wú)法防止文件內(nèi)容被惡意篡改 |
| 信任根源 | 依賴(lài)于權(quán)威、中立的第三方證書(shū)頒發(fā)機(jī)構(gòu) (CA) | 依賴(lài)于提供簽署服務(wù)的平臺(tái)方業(yè)務(wù)邏輯 |
| 典型應(yīng)用場(chǎng)景 | 電子合同、法律文書(shū)、金融交易、財(cái)務(wù)發(fā)票 | 內(nèi)部審批流、普通服務(wù)條款勾選、考勤簽到 |
由上可知,廣義的電子簽名只能記錄簽署意愿,無(wú)法從技術(shù)上保證文件不被篡改。在正式場(chǎng)合中,引入數(shù)字簽名才能為數(shù)字化文件提供可靠的技術(shù)背書(shū)。那么,在實(shí)際的業(yè)務(wù)落地中,數(shù)字簽名又是如何與我們?nèi)粘鏖喌奈臋n結(jié)合在一起的呢?
三、 為什么 PDF 是數(shù)字簽名的最佳載體?
在實(shí)際業(yè)務(wù)中,絕大多數(shù)數(shù)字簽名都是依托 PDF 格式實(shí)現(xiàn)的。這是因?yàn)?PDF(ISO 32000 標(biāo)準(zhǔn))原生內(nèi)置了對(duì)數(shù)字簽名和公鑰基礎(chǔ)設(shè)施(PKI)的支持。
當(dāng)你在 Adobe Acrobat 或其他標(biāo)準(zhǔn) PDF 閱讀器中打開(kāi)一個(gè)帶有數(shù)字簽名的文件時(shí),閱讀器會(huì)自動(dòng)調(diào)用內(nèi)置的證書(shū)庫(kù)或系統(tǒng)證書(shū)庫(kù)來(lái)驗(yàn)證該簽名。如果驗(yàn)證通過(guò),會(huì)醒目地提示“已簽名且所有簽名均有效”;如果文件被篡改,則會(huì)立即彈出警告。這種動(dòng)態(tài)驗(yàn)證機(jī)制比圖片印章等更加嚴(yán)格且準(zhǔn)確。
四、 如何為 PDF 文檔添加標(biāo)準(zhǔn)數(shù)字簽名
了解了數(shù)字簽名的重要性之后,我們?cè)陂_(kāi)發(fā)階段如何落地呢?如果從底層去手寫(xiě) ASN.1 編碼、處理 PKCS#7 簽名結(jié)構(gòu),不僅門(mén)檻高,而且容易造成安全漏洞。
在 Python 生態(tài)中,我們可以借助成熟的類(lèi)庫(kù)來(lái)高效實(shí)現(xiàn)。下面我們將使用 Spire.PDF for Python 庫(kù),演示如何通過(guò)代碼為 PDF 文檔添加一個(gè)包含外觀圖片、簽署人信息的標(biāo)準(zhǔn)數(shù)字簽名。
1. 前置準(zhǔn)備
在運(yùn)行代碼前,請(qǐng)確保已通過(guò) pip 安裝了相應(yīng)的庫(kù),并準(zhǔn)備好你的數(shù)字證書(shū)(.pfx 或 .p12 格式)以及用于展示的電子印章圖片。
pip install Spire.PDF
該組件還提供免費(fèi)版(Free Spire.PDF for Python),滿(mǎn)足基礎(chǔ)開(kāi)發(fā)需求。
2. 代碼示例
以下是完整的 Python 實(shí)現(xiàn)代碼。代碼中利用 PdfOrdinarySignatureMaker 實(shí)現(xiàn)了標(biāo)準(zhǔn)簽名的創(chuàng)建,并對(duì)簽名的視覺(jué)外觀進(jìn)行了精細(xì)化的定制:
from spire.pdf.common import *
from spire.pdf import *
# 創(chuàng)建 PdfDocument 實(shí)例
doc = PdfDocument()
# 加載PDF文件
doc.LoadFromFile("/input/Booklet.pdf")
# 創(chuàng)建 PdfOrdinarySignatureMaker 實(shí)例
signatureMaker = PdfOrdinarySignatureMaker(doc, "/Data/gary.pfx", "e-iceblue")
# 設(shè)置簽名屬性,如簽署人的姓名、聯(lián)系信息、位置和簽名原因
signature = signatureMaker.Signature
signature.Name = "陳艾黎"
signature.ContactInfo = "+86 12345678"
signature.Location = "中國(guó)"
signature.Reason = "我是文檔作者"
# 創(chuàng)建 PdfSignatureAppearance 實(shí)例
appearance = PdfSignatureAppearance(signature)
# 為“簽署人姓名”設(shè)置標(biāo)簽
appearance.NameLabel = "簽署人:"
# 為“聯(lián)系信息”設(shè)置標(biāo)簽
appearance.ContactInfoLabel = "電話(huà):"
# 為“位置”設(shè)置標(biāo)簽
appearance.LocationLabel = "地址:"
# 為“簽名原因”設(shè)置標(biāo)簽
appearance.ReasonLabel = "原因:"
# 設(shè)置簽名圖片
appearance.SignatureImage = PdfImage.FromFile("/signature.png")
# 設(shè)置簽名的圖形渲染/顯示模式
appearance.GraphicMode = GraphicMode.SignImageOnly
# 設(shè)置簽名圖片的布局
appearance.SignImageLayout = SignImageLayout.none
# 獲取第一頁(yè)
page = doc.Pages[0]
# 將簽名添加到頁(yè)面的指定位置
signatureMaker.MakeSignature("簽名", page, 90.0, 650.0, 260.0, 100.0, appearance)
# 保存已簽名的文檔
doc.SaveToFile("/output/數(shù)字簽名.pdf")
doc.Close()
下方為使用代碼在 PDF 中插入數(shù)字簽名的結(jié)果文檔預(yù)覽圖:

3. 代碼技術(shù)要點(diǎn)解析
- 元數(shù)據(jù)與視覺(jué)的分離:代碼中設(shè)置的
signature.Name、Location等信息會(huì)被寫(xiě)入 PDF 的數(shù)字簽名數(shù)據(jù)字典中,即使用戶(hù)在外觀上通過(guò)SignImageOnly隱去了這些文本,簽名屬性面板依然能完整提取并審計(jì)這些合規(guī)信息。 - 不可篡改性:一旦執(zhí)行完
MakeSignature并保存,整個(gè) PDF 的當(dāng)前狀態(tài)就被計(jì)算進(jìn)了哈希。此后若有人試圖用 PDF 編輯器修改文檔中的任何文本,印章處都會(huì)顯示“簽名失效”。
總結(jié)
綜上所述,分清數(shù)字簽名與電子簽名的本質(zhì)區(qū)別,是構(gòu)建安全系統(tǒng)、保障數(shù)字化辦公信息合規(guī)的關(guān)鍵一步。在實(shí)際開(kāi)發(fā)中,我們應(yīng)當(dāng)根據(jù)具體的業(yè)務(wù)場(chǎng)景進(jìn)行選擇:如果只需要快速留痕或記錄用戶(hù)的點(diǎn)擊意愿,采用前端手寫(xiě)板配合日志記錄的通用電子簽名就已足夠;但如果是涉及法律合同、財(cái)務(wù)票據(jù)、合規(guī)審計(jì)等對(duì)防篡改有著嚴(yán)苛要求的使用場(chǎng)景,則更加建議使用數(shù)字簽名保證文件的有效性和完整性。
幸運(yùn)的是,借助于像 Spire.PDF for Python 這樣成熟的組件,開(kāi)發(fā)者無(wú)需深入學(xué)習(xí)密碼學(xué)和 PDF 文件結(jié)構(gòu),只需通過(guò)清晰的 API,就能在短時(shí)間內(nèi)構(gòu)建出既符合合規(guī)審計(jì)標(biāo)準(zhǔn)、又兼顧美觀視覺(jué)外觀的數(shù)字化簽署方案。
到此這篇關(guān)于Python實(shí)現(xiàn)為PDF文檔添加標(biāo)準(zhǔn)數(shù)字簽名的文章就介紹到這了,更多相關(guān)Python PDF添加數(shù)字簽名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)自動(dòng)生成高質(zhì)量文章的示例代碼
在當(dāng)今內(nèi)容為王的時(shí)代,自媒體創(chuàng)作者們面臨著巨大的內(nèi)容生產(chǎn)壓力,每天需要產(chǎn)出大量高質(zhì)量文章來(lái)吸引讀者,下面我們就來(lái)看看如何僅用50行Python代碼打造一個(gè)自動(dòng)文章生成器吧2025-06-06
Pycharm配置遠(yuǎn)程SSH服務(wù)器實(shí)現(xiàn)(切換不同虛擬環(huán)境)
本文主要介紹了Pycharm配置遠(yuǎn)程SSH服務(wù)器實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
python新手練習(xí)實(shí)例之萬(wàn)年歷
最近進(jìn)行python基礎(chǔ)培訓(xùn),課下作業(yè)制作萬(wàn)年歷,之前沒(méi)做過(guò),感覺(jué)里面還是有很多需要學(xué)的,下面這篇文章主要給大家介紹了關(guān)于python新手練習(xí)實(shí)例之萬(wàn)年歷的相關(guān)資料,需要的朋友可以參考下2022-05-05
python各層級(jí)目錄下import方法代碼實(shí)例
這篇文章主要介紹了python各層級(jí)目錄下import方法代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Python 實(shí)現(xiàn)try重新執(zhí)行
今天小編就為大家分享一篇Python 實(shí)現(xiàn)try重新執(zhí)行,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12

