COMIC CLASSROOM

安全基礎第 6 / 9 課

數位簽章漫畫小教室:這份訊息,真的是你發的嗎?

一張維修通知,從冒名、金額被改到公鑰驗證;十二張漫畫帶你理解數位簽章如何運作,以及驗證成功後還要檢查什麼。

13 分鐘

一封通知到了,先相信哪一件事?

看到熟悉的名字,你可能願意打開通知;要照著付款,還需要更可靠的依據。這篇從機器人差點相信一封假信開始,逐步補上檢查內容與來源的方法。

先跟著故事讀,不必記住所有縮寫。等你能說清楚誰負責簽、誰負責驗,再往下看:為什麼亮起綠勾,仍不代表這筆付款現在就該執行?

一張寫著 100 元的維修通知,途中被改成 900 元,寄件人名稱卻沒變。只看名稱,機器人可能照單付款。數位簽章讓它用公鑰檢查收到的內容與簽章是否相符;付款前,還要知道公鑰屬於誰、通知是否仍有效,以及簽署者有沒有這項權限。

下面用這份虛構通知串起十二張漫畫,從複製印章、計算摘要走到簽署與驗證。圖上的手寫符號代表簽章資料;真正檢查的是資料與金鑰之間的數學關係。文末可用瀏覽器簽一次通知,再改金額或換驗證公鑰。這能實際觀察驗證成敗,但頁面沒有可信身分綁定,不能證明簽署者是 MY。

1. 名字對了,就能相信?

數位簽章漫畫第 1 頁:名字對了,就能相信?
圖 1:寄件人名字相同,來源與內容仍要分別檢查。

機器人收到一張維修通知,上面寫著「寄件人:MY 老師」。金額只有 100 元,格式也熟悉,它便準備照著通知付款。這時老師攔住它:你認得這個名字,但你怎麼知道,填上名字的人真的是我?

這是一個虛構的教學情境,卻很接近日常收到的郵件和下載通知。電腦看到的是一串資料;寄件人名稱、頭像和文件上的署名,都可能只是資料裡可以複製的欄位。外觀再像,也還沒有完成來源驗證。

再看第二個問題。假設通知確實由老師寄出,途中有人把 100 改成 900,寄件人欄位仍然一字不差。確認作者與確認內容沒有被改,是兩項相關但不同的工作。只有一項成立,機器人仍可能做錯事。[2]

上一課 HRoT 談的是把重要金鑰和使用權限保護好。這一課接著看:受保護的私鑰如何替一份訊息留下別人能檢查的證據。沿著這封通知的故事,公鑰與簽章各自負責什麼就會逐漸清楚。

2. 貼上簽名或印章,為什麼不夠?

數位簽章漫畫第 2 頁:貼上簽名或印章,為什麼不夠?
圖 2:同一張印章圖片可以貼到不同通知上。

機器人想到一個辦法:請老師在通知上蓋章。壞人卻只做了兩個動作,剪下印章、貼到另一張通知。新的通知寫著 900 元,章還是原來那個章。

紙本文件可能搭配筆跡、紙張、收件程序等線索判斷真偽。搬到電腦上後,一張掃描簽名圖本身很容易被複製。即使人眼看不出差別,也無法只靠這張圖確定旁邊那段文字是否仍是老師同意的內容。

數位簽章要建立的是內容與簽署能力之間的數學關係。驗證者把收到的訊息放進檢查,若有人換了文字,舊簽章就不能被當成另一份內容的有效證據。這個機制不依賴印章畫得多複雜。[1]

因此,PDF 上看得見的簽名圖與檔案裡真正的數位簽章可以同時存在,卻各有角色。前者方便人辨識,後者才參與密碼學驗證。接下來先處理內容:一份長長的文件,怎麼交給電腦有效率地比對?

3. 訊息怎麼留下短指紋?

數位簽章漫畫第 3 頁:訊息怎麼留下短指紋?
圖 3:同樣內容得到同樣摘要;色塊是示意,碰撞並非不可能。

把通知送進雜湊函數,可以得到一段固定長度的摘要。先把它想成電腦替內容算出的指紋:相同資料使用相同函數,會得到相同結果。圖上的色塊只是幫助辨識的示意,不是真正可以使用的摘要。[5]

如果把通知裡的 100 改成 900,摘要通常會大幅改變。這讓摘要很適合用來發現內容差異。不過,固定長度的輸出能表示的結果有限,輸入卻可以非常多,因此不同訊息產生相同摘要的碰撞並非不存在。安全設計要求的是,攻擊者難以有效找到能利用的碰撞。[5]

摘要不包含可還原完整通知的壓縮資料,也不會自動替容易猜的內容保密。若通知只有幾個候選金額,旁觀者仍可逐一雜湊,再和已知摘要比對。難以從摘要找出原像,和難以猜中一份範圍很小的通知,是不同條件下的問題。

對這封通知而言,摘要先提供一種檢查內容的方法。但機器人手上那份「預期摘要」到底從哪裡來?如果它和通知一起來,而且途中都能被換掉,我們才剛走到問題的一半。

4. 連摘要一起換掉,比對還會成功?

數位簽章漫畫第 4 頁:連摘要一起換掉,比對還會成功?
圖 4:通知與摘要一起被換掉,重新計算仍可能相符。

老師替 100 元通知算出摘要 A,並把兩者一起寄走。壞人攔下來,把通知改成 900 元,再用同一個雜湊函數算出摘要 B。最後寄給機器人的,是新通知加上新摘要。

機器人忠實地照程序做:收到 900 元通知,自己算一次,結果正好是 B。檢查通過了。可是這次通過,只表示收到的通知與收到的摘要彼此相符;它並沒有證明老師曾經發過這份內容。

攻擊者在這裡完全沒有破解雜湊函數。雜湊演算法本來就是公開的,任何人都能替任意資料計算摘要。即使換成另一個安全的雜湊函數,只要通知和比對基準都可被替換,這條攻擊路徑仍然存在。

若預期摘要來自另外一條已驗證、不可被同時替換的管道,比對當然可以發揮作用。因此問題不能簡化成「hash 沒用」。真正要追的是信任來源:機器人憑什麼相信手上的比對基準?數位簽章將把這個問題接到一把受信任的公鑰上。[2]

5. 人人能驗證,卻不能人人冒簽

數位簽章漫畫第 5 頁:人人能驗證,卻不能人人冒簽
圖 5:私鑰留在簽署端,公鑰讓接收者自行驗證。

老師這次準備一對有數學關聯的金鑰。私鑰留在自己控制的地方,用來產生簽章;公鑰可以交給機器人,讓它檢查簽章。公鑰公開的目的,就是讓接收者有辦法自行驗證。

兩者並不是權限相同的兩把備份鑰匙。知道公鑰,並不應讓攻擊者有效算出私鑰或替任意新訊息冒簽。這個不對稱性,是數位簽章能公開驗證的基礎。它也仰賴選對方案、足夠的參數和正確實作。[1]

先別把簽署想成把信鎖進箱子。這份維修通知仍可直接閱讀;簽章讓接收者檢查內容與金鑰的關係,沒有把金額藏起來。加密處理誰看得到內容;在公鑰來源可信、私鑰受適當控制等條件下,簽章支援來源與內容完整性的驗證。[2]

如果讀過 RSA,你可能見過公私鑰的冪次運算;那不能直接推成「所有簽章都是私鑰加密」。不同方案有不同算法,公開驗證也不是把簽章解密成原文。這裡先記住兩個角色就好:私鑰簽署,公鑰驗證。

這兩頁暫時假定機器人拿到的公鑰確實屬於老師。這個假設很重要,第 8 頁會刻意把它拿掉,看看會發生什麼。

6. 一次完整的簽署與驗證

數位簽章漫畫第 6 頁:一次完整的簽署與驗證
圖 6:訊息與簽章可以傳送,私鑰不必交給驗證者。

把訊息記為 m,私鑰記為 sk,簽章記為 s。s = Sign(sk, m) 的意思很單純:簽署程序使用私鑰與這份訊息,產生對應的簽章。這行是描述輸入與輸出的記號,並不是讓你自行實作密碼學的公式。

老師把 m 和 s 交出去,私鑰留在原處。機器人收到後,另外拿出已信任的公鑰 pk,計算 Verify(pk, m, s)。驗證結果回答這組公鑰、訊息與簽章是否符合所選方案的規則。

驗證沒有要求機器人向老師索取私鑰。若接收者也要拿到私鑰才能檢查,它便同時取得冒簽能力,公開驗證的分工就被破壞了。圖中跨過傳送箭頭的只有訊息和簽章。

雜湊在常見簽章方案中扮演重要角色,但實際由哪一層處理,要依方案與函式庫介面決定。某些介面接收完整訊息,另一些明確接收預先計算的摘要。應用程式不能自己多 hash 一次,再假定接收端一定會以同樣方式驗證。[3]

所以做系統整合時,除了金鑰,雙方還得對訊息格式、簽章方案和驗證規則有相同理解。這些條件固定後,才適合拿剛才的 100 元通知,做一次真正的竄改測試。

工程師延伸:完整訊息介面與預雜湊介面,是不同契約

RFC 8032 區分 PureEdDSA 與預雜湊變體。應依確切方案及函式庫介面決定輸入,不能習慣性地先 hash 再呼叫。主文的 Sign 與 Verify 記號省略內部步驟,是為了說明不同方案共有的角色,不代表各方案內部做法相同。

7. 把 100 改成 900,舊簽章還能用嗎?

數位簽章漫畫第 7 頁:把 100 改成 900,舊簽章還能用嗎?
圖 7:同一把可信公鑰下,改後資料無法沿用原簽章。

老師為 100 元通知產生簽章 s。機器人用老師的公鑰驗證,結果有效。現在只改一件事:把收到的通知改成 900 元,保留 s 和同一把公鑰,再驗證一次。

在本課使用的正常、安全方案與這組不同訊息下,第二次驗證會失敗。壞人不能靠剪貼原簽章,讓它自動變成 900 元通知的有效證據。若想讓新內容通過,必須取得相應的簽署能力,或攻破方案或實作中的某個假設。[1]

電腦檢查的是實際送進簽署程序的資料,不是人腦理解的意思。兩份看起來相同的文件,可能因換行、編碼或空白不同而有不同的位元內容;若中間系統自行改寫,合法訊息也可能驗證失敗。

反過來,若只簽了金額,卻把收款人放在未受保護的欄位,攻擊者可能只改收款人,讓金額那部分的簽章仍然有效。要保護的資料有哪些,必須在簽署格式裡說清楚。簽章不會自動覆蓋畫面上每一個欄位。

遇到無效結果時,不能直接斷定有人行騙;傳錯 key、檔案損壞或雙方格式不一致都可能造成失敗。安全處理是先停止依賴該證據,再查原因,不能為了讓流程繼續而忽略驗證。

工程師延伸:把影響決策的欄位都納入簽署

簽署格式應明確涵蓋收件者、金額、操作和必要情境,並避免有多種解讀方式。若採用正規化讓等價的結構化資料得到相同位元組,簽署端與驗證端必須遵守同一套規則。系統應確認最後執行的資料正是已驗證的內容,避免驗證一份資料卻執行另一份未綁定的表示。

8. 用壞人的公鑰,為什麼也能通過?

數位簽章漫畫第 8 頁:用壞人的公鑰,為什麼也能通過?
圖 8:用攻擊者的公鑰驗證成功,並未證明老師的身分。

壞人不再修改老師簽好的通知。這次,他產生自己的金鑰對,用自己的私鑰簽一封新信,再把自己的公鑰一起寄給機器人,附上一句:「這是 MY 老師的公鑰。」

機器人拿這把公鑰去驗證,結果真的有效。數學沒有失靈:那封信確實由與這把公鑰相對應的私鑰簽出。出錯的地方是機器人把一個未確認的名字,貼到了一把陌生公鑰上。

因此,驗證成功可以先理解成「這份資料的簽章與這把 key 相符」。要再往前說「是老師簽的」,還要有可信的身分連結,而且私鑰仍受適當控制。信任不能只靠寄件者自己附的一句宣稱。[1][4]

實務上,系統可能預先保存受信任的公鑰,透過已驗證的其他管道確認指紋,或使用憑證與既定信任規則。哪一種做法適合,要看裝置如何出廠、誰有更新權限,以及它要與哪些對象互動。

本課先把缺口看清楚。下一課的憑證與 PKI,才會回答誰替公鑰身分背書、驗證者從哪個起點相信這份背書。先拿到綠勾,再問綠勾究竟對哪一把 key 負責。

9. 有效的簽章,還沒回答哪些事?

數位簽章漫畫第 9 頁:有效的簽章,還沒回答哪些事?
圖 9:錯誤內容、舊通知和明文閱讀,各自需要不同判斷。

老師可能真的把維修費寫錯,再親自簽署。這時簽章仍可有效,因為它檢查資料與 key 的關係,並不替老師重新估價。來源可以驗證,內容的正確性仍需另外判斷。

另一個例子是昨天的通知。壞人把一份舊的、簽章有效的付款指示原封不動再寄一次,簽章並不會因為今天換了日期而自然失效。接收端需要知道這筆請求是否已處理、是否仍在允許期間,並按自己的規則拒絕重複執行。

保密也是另一件事。如果通知以明文傳送,旁觀者仍能讀到金額。加上一份簽章,不會把訊息變成密文。NIST 對數位簽章的說明也明確區分了來源與完整性保護,以及它本身不提供的機密性和重放防護。[2]

你可能還聽過「不可否認性」。簽章能成為第三方檢驗的證據,但把它解讀成某人永遠無法否認,就跳得太遠了。金鑰如何連到身分、由誰控制、何時可能外洩,都會影響能作出的判斷;法律效果還需相應制度,這篇不把數學驗證寫成法律保證。[1][4]

機器人最後要做的是付款,而不只是讓驗證畫面亮綠燈。它仍須檢查對方是否有收款權限、通知是否適用、這次是否該執行。這些判斷應建立在驗證結果之上,不能被驗證結果取代。

10. 保護私鑰,也要保護簽署權限

數位簽章漫畫第 10 頁:保護私鑰,也要保護簽署權限
圖 10:私鑰留在硬體內,仍要拒絕未授權的簽署請求。

老師把私鑰放進受保護硬體,任何一般程式都讀不到。看起來很放心。可是如果每個程式都能呼叫「請幫我簽這份通知」,壞人只要送入自己的假通知,就可能取得一份真正有效的簽章。

這回沒有 key 外流。被濫用的是簽署服務。HRoT 要守住的除了祕密資料,還有誰可以提出請求、能要求哪種操作,以及這份操作在當下是否被允許。上一課的存取控制,在這裡有了很具體的用途。

例如,維修通知服務可以被限定為替某種格式的通知簽署,請求須來自核准的程式或工作流程。敏感情境還需要額外授權與紀錄。這些是系統可以採用的控制方式,並非只要放進一顆安全晶片就會自動具備。

若私鑰真的被複製,攻擊者可能在裝置外持續冒簽。換一個密碼介面或重新啟動機器,並不會讓那份副本消失。系統要能停止依賴已失守的 key、建立新的信任材料,並讓驗證者得知變更。[4]

金鑰撤銷與輪替的詳細流程留給後續單元。這裡先記住兩條不同的防線:避免私鑰被取走,並避免合法簽署能力被拿來做未授權的事。

工程師延伸:硬體邊界仍需要服務政策

不可匯出的 key handle 限制了提取,卻不自動限制所有操作。呼叫者隔離、允許用途、生命週期狀態與授權檢查,共同決定誰能使用這個 handle。這些架構選擇要依威脅模型驗證效果,不能只看到硬體加密引擎就推定保護完整。

11. 不同算法,保留同一組分工

數位簽章漫畫第 11 頁:不同算法,保留同一組分工
圖 11:先分清角色,再辨認 RSA、ECDSA 與 EdDSA 的方案。

到這裡,讀者已經能說明一份簽章在做什麼。接著看到 RSA、ECDSA 或 EdDSA,就可以先把它們放進同一張角色圖:簽署端持有私鑰,驗證端使用公鑰。

RSA 的數學可以用來建立簽章方案,也可以出現在加密方案中;兩種用途有各自的規則,不能拿前一課的小數字加密例子直接當成正式簽章做法。名稱裡都有 RSA,並不代表整套流程可以互換。

ECC 則指向橢圓曲線密碼學這個領域與數學基礎。ECDSA、EdDSA 是建立在橢圓曲線上的不同簽章方案,並不是替同一個東西隨意換名字。FIPS 186-5 包含 RSA、ECDSA 和 EdDSA 的簽章規定;RFC 8032 另外描述了 EdDSA 的具體變體。[1][3]

現在不需要把三種算法各自推導一次。選用時,工程師需要指定確切方案、參數與函式庫介面,不能只交代「我們用 ECC」便認為其他人知道如何驗證。實作也要處理錯誤輸入與金鑰使用的邊界。

這張關係圖的用途,是讓你讀產品或技術文件時找對層次。先問它負責簽署還是驗證,再看採用哪套方案,最後回到公鑰來源與使用政策。

12. 回到通知,你能看出哪裡出問題?

數位簽章漫畫第 12 頁:回到通知,你能看出哪裡出問題?
圖 12:沿著資料、金鑰身分與使用規則,找出真正失守的位置。

再把第一頁的通知拿出來。現在我們不會只看寄件人名字,也不會因為旁邊附了一串摘要就立刻付款。機器人需要知道拿哪把可信公鑰,對哪份資料、哪個簽章做檢查。

若 100 元被改成 900 元,而原簽章沒有變,應先在驗證這一步擋下。若攻擊者連公鑰都冒稱老師的,問題就出在 key 的身分來源。兩種狀況都可能呈現成一封假通知,補救的地方卻不同。

若通知確實由老師簽出,但只是被重新寄送,機器人還要查處理紀錄與時效。若壞人能操控簽署服務,則要回頭檢查呼叫者與授權。沿著這條路徑看,就比較不容易把所有問題都歸給「算法不夠強」。

數位簽章把資料與特定金鑰連起來,讓驗證者有可以檢查的證據。身分、授權與時間,決定這份證據在當下能支持什麼行動。這也解釋了為什麼硬體安全需要多個元件與服務合作。[2]

最後留下一個還沒完整回答的問題:如果我從來沒見過老師的公鑰,誰可以替它背書?下一課「憑證與 PKI」從這裡開始。等公鑰身分有了依據,再把簽章驗證接進 Secure Boot,才看得懂晶片開機時究竟相信了什麼。

五點帶走

  1. 熟悉的名字或印章,不足以把來源與這份訊息綁在一起。
  2. 比對摘要需要可信基準;訊息與附上的摘要可能被一起替換。
  3. 私鑰簽署、公鑰驗證;簽章不會隱藏訊息。
  4. 驗證有效後,還要確認公鑰身分、授權與時效。
  5. 金鑰不能被偷走,簽署服務也不能被任意濫用。

下一課是「憑證與 PKI」:陌生的公鑰由誰背書,驗證者又憑什麼相信?之後再用 Secure Boot,把這些觀念接進晶片開機流程。

References

  1. NIST, Digital Signature Standard (FIPS 186-5, 2023)
  2. NIST CSRC Glossary, Digital signature
  3. RFC 8032, Edwards-Curve Digital Signature Algorithm (EdDSA), 2017
  4. NIST SP 800-57 Part 1 Rev. 5, Recommendation for Key Management, 2020
  5. NIST FIPS 180-4, Secure Hash Standard, 2015

簽一次,再改內容與驗證公鑰

按「建立並簽署」為 100 元維修通知產生新金鑰與簽章。先驗證原文,再只改 100 成 900。還可以用另一把公鑰驗證。每次只改一項,分辨內容被改與公鑰不符。

使用瀏覽器 Web Crypto 的 ECDSA P-256/SHA-256 真實簽署與驗證。私鑰不可匯出,僅留在本頁記憶體;沒有憑證或可信身分綁定,成功不能證明簽署者是 MY。請只用教材內容。

學習指南

安全基礎

0 / 9

查看課程大綱 → · 進度只計入已發布課程

先備知識

  • 不要求算法數學;讀過 SHA 與 HRoT 會更容易銜接

我學會了什麼

  • 解釋單獨附上摘要為何無法驗證寄件人
  • 看懂私鑰簽署與公鑰驗證的完整流程
  • 區分簽章有效、公鑰身分、時效與授權
  • 辨認公鑰替換與簽署服務濫用

本課術語

查看術語字典 →

延伸閱讀

課後小測驗

1. 產生數位簽章使用哪把金鑰?
2. 攻擊者同時替換訊息與附上的 hash,可能發生什麼?
3. 陌生寄件者附上公鑰,簽章驗證成功。還缺少什麼?
4. 私鑰不能匯出,但任何 App 都能要求任意簽署。缺了什麼?
5. 舊的已簽署命令原封不動再送一次,接收端還需要什麼?

讀到這裡,辛苦了。

把概念帶走,比把術語背走更重要。

#Digital Signature#數位簽章#Hash#公鑰#私鑰#HRoT#硬體安全#漫畫小教室