數位簽章如何證明是誰簽的
Spec: RFC 5652RFC 5652Spec: RFC 5280, §6RFC 5280 §6Spec: RFC 3161, §1RFC 3161 §1
一個數位簽章做三件事,而且值得從一開始就把它們分開來看:它證明那些位元組沒被改過、它證明是誰簽的,而且——稍加協助——它證明何時。本頁從零建立起這個概念,好讓密碼學不再是一個黑盒子。
為何這很重要
標題為「為何這很重要」的區段「已簽署」是一個讓人據以下決定的字眼。一份合約、一張發票、一份某人即將執行之軟體的發行說明。如果你只知道某個工具印出了一個綠色勾勾,你其實並不知道究竟證明了什麼。你或許握有那些位元組完好無缺的證明,卻對是誰的金鑰簽了它們毫無頭緒。你或許有一個真實的簽署者,卻配上一張數年前就過期的憑證。理解這些組成部分,正是讓你能精確地說出一個有效簽章意味著什麼的關鍵——而同樣有用的是,說出它不意味著什麼。
精簡版
標題為「精簡版」的區段想像一個防拆封的信封,封口上壓著一枚個人印鑑。
- 印鑑對一個人而言是獨一無二的,且實質上不可能偽造。任何人都認得它;只有它的擁有者能做出它。那就是金鑰對:一把只有你持有的私鑰,與一把人人都看得到的公鑰。
- 你不是把印鑑壓在整份文件上。你把它壓在文件一個微小、不可偽造的摘要上——一個雜湊。改動文件的一個位元組,摘要就完全改變,於是印鑑不再吻合。
- 簽署是用你的私鑰對文件產生一個簽章——對 RSA 與 ECDSA 而言是對雜湊,對 EdDSA 而言則是對內容本身,後者在內部自行做雜湊。驗證是用你的公鑰、那個簽章與同一份內容(以雜湊形式,或直接以內容)執行該演算法的查驗——它回傳有效或無效。連結這兩者的是數學,而非信任。
- 憑證是說出這是誰的印鑑的那一部分。少了它,你證明了某把金鑰簽了那些位元組,卻沒證明那把金鑰屬於任何特定的人。
- 時間戳是說出何時的那一部分。一個簽署者自己的時鐘只是一項聲稱;受信任的時間來自一個外部權威。
NextPDF 如何看待它
標題為「NextPDF 如何看待它」的區段從雜湊開始,因為其餘的一切都立基於它。一個密碼學雜湊函式讀入任意數量的資料,並產生一個簡短、固定長度的指紋——對一個 PDF 簽章而言,通常是一個 256 位元的值。有兩項性質讓它有用:相同的輸入永遠產生相同的指紋,而且要找到一個產生同一指紋的不同輸入是不可行的。所以雜湊是文件一個忠實的替身。若兩個雜湊吻合,那些位元組就吻合。
接著是金鑰對。一把私鑰與一把公鑰在數學上相連,但你無法在任何可行的時間內從其中一把推導出另一把。只有私鑰能產生一個有效簽章,也只有相符的公鑰能查驗它。簽署利用的就是那份不對稱:簽署者對所選演算法所定義的輸入施加一次私鑰運算——對 RSA 與 ECDSA 而言是內容的雜湊,對 EdDSA 而言則是直接對內容,後者在內部做雜湊。其結果就是簽章值。因為只有私鑰的持有者才可能產生它,又因為它被綁定在這份內容上,所以它一次證明了兩件事——持有者簽了,且那些位元組自此未曾移動。
驗證映照了那套邏輯。驗證者重建出同一個輸入——對 RSA 與 ECDSA 而言是對文件做雜湊,對 EdDSA 而言則是直接取用內容——然後對公鑰、簽章值與該輸入執行該簽章演算法的驗證運算。該運算回傳有效或無效——而無論演算法是 RSA、ECDSA 或 EdDSA,這個形貌都相同,即便只有 RSA 能被描繪成字面意義上「還原」出雜湊。有效意味著完好且真確。無效意味著有東西被改過,或用錯了金鑰,而那個誠實的答案就是無效。
- Prepare the inputRSA and ECDSA hash the document to a short, fixed-length fingerprint; EdDSA signs the content directly and hashes it internally. Either way, any change to the bytes changes what is signed.
- Sign with the private keyThe signer applies a private-key operation to that input — the hash for RSA and ECDSA, the content for EdDSA. The output is the signature value; only the private-key holder could have produced it.
- Reconstruct the inputThe verifier independently rebuilds the same input from the content — a recomputed hash for RSA and ECDSA, the content itself for EdDSA. This is what the verify operation checks against.
- Verify with the public keyThe verifier runs the algorithm's verify operation on the public key, the signature value, and that input. The same shape works for RSA, ECDSA, and EdDSA.
- Accept or rejectThe verify operation returns valid or invalid. Valid means the bytes are intact and the private-key holder signed them. Otherwise the result is invalid — no guessing.
在一份真實的 PDF 裡,NextPDF 不是把印鑑壓在可見的頁面上——它把印鑑壓在一段宣告的位元組範圍上,並把簽章封裝成一個分離式 CMS 物件(Spec: RFC 5652RFC 5652),置於檔案內部(Spec: ISO 32000-2, §12.8ISO 32000-2 §12.8)。有一項細緻之處很重要:簽署者並不直接簽署原始的內容雜湊。它簽署的是一小組已簽署屬性,這組屬性包含內容的雜湊,因此時間、內容類型與簽署者的憑證識別符全都被一同封緘。那些位元組存在何處、以及該範圍為何被塑造成那樣,是 簽章如何坐落於一份 PDF 中 的主題。
到此為止,數學證明了某把金鑰簽了這些位元組。它對是誰的金鑰隻字未提。那道缺口正是一張憑證所填補的。一張憑證本身就是一份已簽署的陳述——來自一個憑證機構——聲明這把公鑰屬於這個具名的主體。信任它意味著沿著從簽署者憑證一路向上、到一個你已決定信任之權威的鏈條,逐一查驗沿途每一個環節的有效性(Spec: RFC 5280, §6RFC 5280 §6)。少了那條鏈,「已簽署」是匿名的。有了它,「已簽署」就有了一個名字。
最後一塊是何時。一個簽章可以嵌入簽署者自己宣稱的時間,但一個你無法掌控的時鐘是一項聲稱,而非一個證明。一個來自時間戳機構(Time-Stamp Authority)的時間戳,把簽章的一個雜湊綁定到一個瞬間,由一個對該文件毫無利害關係的一方加以證實(Spec: RFC 3161, §1RFC 3161 §1)。那正是讓一個簽章在簽署者憑證過期之後仍保有意義的關鍵:你能展示該簽章在該憑證仍有效時就已存在。更深入的處置在 時間戳與受信任的時間。
實務範例
標題為「實務範例」的區段下方的形貌是那些概念性的運算,以白話寫出。重點不在一次 API 呼叫——而在看見簽署與驗證是彼此的鏡像,以及一個被竄改的位元組會從構造上破壞那份吻合。
<?php
declare(strict_types=1);
// SIGN — the holder of the private key seals the content.// RSA and ECDSA sign a hash; EdDSA signs the content directly (hashing inside).$signingInput = sign_input($content); // a digest for RSA/ECDSA, the content for EdDSA$signatureValue = private_key_transform( // only the key holder can do this privateKey: $signerPrivateKey, input: $signingInput,);
// VERIFY — anyone with the public key runs the algorithm's check.$recomputedInput = sign_input($content); // verifier rebuilds the same input$intactAndAuthentic = signature_verify( // RSA, ECDSA, EdDSA — same shape publicKey: $signerPublicKey, // taken from the certificate signatureValue: $signatureValue, input: $recomputedInput, // the freshly reconstructed input);// true -> bytes unchanged AND signed by the private-key holder// false -> a byte changed, or the wrong key — the honest answer is "invalid"
// The certificate answers a SEPARATE question: whose public key is this?// The timestamp answers ANOTHER: when did this signature exist?// "intact + authentic" alone proves neither identity nor time.偽造一個仍能通過驗證的改動,在計算上是不可行的。雜湊忠實地承載著內容,所以更動內容就會更動雜湊,而驗證運算會拒絕它——除非找到一個雜湊碰撞,而所選的函式正是被設計成讓那件事不切實際。
常見誤解
標題為「常見誤解」的區段最常見的錯誤是把「有效的簽章」讀成「值得信任的文件」。它們不是同一個句子。密碼學證明的是那些位元組完好與私鑰的持有者簽了它們——僅此而已。一份用你從沒聽過的金鑰簽署、由你不認得的權威所證實的文件,可以是無懈可擊地「有效」、卻一文不值。身分來自憑證及其鏈條;時間來自一個受信任的時間戳。一個悄悄把這一切全折疊進單一布林值的綠色勾勾,已經替你決定了哪些問題才重要。知道這些組成部分,正是讓你能去問其餘問題的關鍵。
限制與邊界
標題為「限制與邊界」的區段本頁解釋的是一個數位簽章的概念,而非完整的驗證程序。此處的數學證明了完整性與真確性。它並未單憑自身就告訴你:那張簽署憑證是否確實核發給你以為的對象、它在簽署當下是否有效,或它後來是否被撤銷——那些是憑證路徑與撤銷的問題,而一次正確的驗證會把它們全部跑過。完整的查驗集合在 正確地驗證一個簽章。
NextPDF 建立簽章結構並執行密碼學查驗。它不替你選擇你的信任錨、不為任何憑證機構背書,也不裁定一個簽章的法律效力——那些取決於你的部署、那張憑證,以及該管轄區。引擎證明的是那套機制;建立在它之上的信任決定則屬於你。
引擎按層級所交付的東西,從這個基礎向外建構:
| Edition | Availability |
|---|---|
| Core | PAdES B-B:此處所述的雜湊與簽署機制,封裝成一個分離式 CMS SignedData 物件,外加對著一個你提供之信任錨所做的憑證路徑驗證。 |
| Pro | 增添 PAdES B-T——在簽章值上加上一個經查驗的 RFC 3161 受信任時間戳,讓那個「何時」是被證實的、而非自行聲稱的。 |
| Enterprise | 增添長期設定檔(B-LT、B-LTA):嵌入的驗證材料與文件時間戳,讓身分與時間的證明在數年間仍可被回答。 |
相關文件
標題為「相關文件」的區段- 簽章如何坐落於一份 PDF 中——簽章值及其位元組範圍實際上存在於檔案中的何處。
- 正確地驗證一個簽章——一個驗證者必須執行的完整查驗集合,超出本頁上的數學之外。
- 時間戳與受信任的時間——一個 RFC 3161 時間戳證明了什麼,以及為何一個簽署者自己的時鐘並不是它。
- PAdES 基準設定檔——哪一個設定檔把身分、時間與長期材料層疊到這個基礎上。
詞彙表
標題為「詞彙表」的區段- 雜湊(摘要)——出自一個密碼學雜湊函式、資料的一個簡短、固定長度的指紋;對資料的任何改動都會把它完全改變。
- 金鑰對——一把相連的私鑰(只由簽署者持有)與公鑰(自由分享);只有私鑰能簽署,也只有相符的公鑰能驗證。
- 簽署——對演算法所定義的輸入施加私鑰運算:對 RSA 與 ECDSA 而言是內容的一個雜湊,對 EdDSA 而言則是直接對內容(後者在內部做雜湊)。在一份 PDF 裡,那份內容是已簽署屬性,其中包含文件的雜湊。其結果就是簽章值。
- 驗證——重建出同一個輸入(一個重新計算的雜湊,或對 EdDSA 而言直接是內容),然後對公鑰、簽章值與該輸入執行該演算法的驗證運算,以取得一個有效或無效的答案。
- 簽章值——私鑰運算所產生的那些位元組;驗證者拿來對著新鮮重建之演算法輸入(對 RSA 與 ECDSA 而言是一個摘要,對 EdDSA 而言是內容本身)查驗的東西。
- 憑證——一份把一把公鑰綁定到一個具名身分的已簽署陳述;藉由鏈接到一個你接受的權威而被信任(RFC 5280 §6)。
- 信任錨——一個你已決定信任的憑證機構;一條可接受之憑證鏈的根。
- 時間戳(RFC 3161)——一個來自時間戳機構(Time-Stamp Authority)的已簽署權杖,把一個雜湊綁定到一個時間值,提供關於何時的受信任證明。
- CMS SignedData——承載簽章值與簽署者憑證的密碼訊息語法(Cryptographic Message Syntax,RFC 5652)結構。
- PAdES——PDF Advanced Electronic Signatures:用於 PDF 簽署的 ETSI 設定檔系列。在各簽署頁面有深入涵蓋。