JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

二十分鐘看懂密碼學:金鑰、雜湊、簽章

上一篇點名了敵人——竊聽、偽冒、中間人。這一篇把反擊的三件工具交到你手上:用金鑰守住機密、用雜湊守住完整性、用簽章守住真實性。不需要高深數學,只需要你真的能在腦中畫出來的清晰想法。

三項任務,三件工具

上一篇你認識了威脅,也認識了目標:機密性、完整性、可用性所組成的 CIA 三要素。密碼學主要處理前兩項。它做三件具體的工作,而只要你把它們分開來看,整個主題就友善多了。機密性是指只有指定的讀者能讀懂訊息——這是加密的工作。完整性是指就算訊息在傳輸途中只被改了一個位元,你也能察覺——這是雜湊與訊息鑑別碼的工作。真實性是指你能證明某樣東西究竟是誰送出的——這是數位簽章的工作。

開始之前有個關鍵提醒:別把這三件工作搞混。加密一則訊息「不」代表能證明是誰送的,也「不」保證沒人動過手腳。一則訊息可以完全保密,卻仍是偽造的,或是抵達時已經被打亂。這正是讓聰明的攻擊者鑽空子的錯誤,所以我們會把保密、完整性、真實性當成三個各自獨立的問題來處理——它們只是恰好用相關的數學來解決而已。

機密性:共享金鑰與分發難題

最古老的想法是 對稱式加密:雙方共享一把祕密金鑰,同一把金鑰既上鎖也解鎖。想像一個保險箱,配了兩把一模一樣的實體鑰匙——你一把、你朋友一把。像 AES 這樣的現代對稱加密法極快,正確使用時實際上無法破解,所以網路上幾乎所有大量資料最終都是用這種方式保護的。明文進去,金鑰把它打亂成看起來像隨機雜訊的密文,只有相符的金鑰才能還原。

但這裡有個雞生蛋、蛋生雞的卡關,而它正是所有密碼學的核心戲劇:金鑰分發難題。要和一個你從沒造訪過的網站祕密交談,你們得先擁有同一把祕密金鑰——但你們唯一能用來商定它的管道,正是那個你不信任的網際網路。如果你把金鑰丟上開放網路寄出去,上一篇那位竊聽者只要照抄一份就好。你也沒辦法加密這把金鑰,因為加密它又需要一把你還沒分享出去的金鑰。光靠對稱式加密,無法在陌生人之間建立起信任。

解法是這個領域裡最美的想法:公開金鑰密碼學。每一方都產生一對相配的金鑰——一把可以向全世界大聲喊出來的公鑰,和一把不告訴任何人的私鑰。兩者在數學上相連,使得無論哪一把鎖上,都只有另一把能解開。妙處在於:如果我用「你的」公鑰加密一則訊息,就只有「你的」私鑰能打開它。我可以在任何地方找到你的公鑰,甚至在不可信的網路上大聲喊出來,竊聽者也學不到任何有用的東西——因為公鑰只能上鎖,不能解鎖。下面這個掛鎖與信箱的比喻會讓你豁然開朗。

Alice wants to send a secret to Bob:

  Bob's public key  = an open padlock Bob mailed everywhere
  Bob's private key = the only key that opens that padlock

  Alice: puts message in box, snaps Bob's padlock shut  -> ciphertext
  Anyone on the wire: sees a locked box, cannot open it
  Bob:   uses his private key (kept secret)             -> plaintext

Nobody ever had to share a secret in advance.
把公開金鑰加密想成一把可以郵寄的掛鎖:任何人都能替 Bob 把盒子鎖上,卻只有 Bob 打得開。

公開金鑰的數學很慢——慢到根本不可能拿來加密一整通視訊通話。所以真實的網際網路用的是混合做法:公開金鑰密碼學負責「商定一把全新的對稱金鑰」(或做金鑰交換)這個小而困難的工作,然後由快速的對稱式加密去加密真正的資料。那段交握,正是 TLS 在每一條 HTTPS 連線開頭所做的事,也正是下一篇的主題。

完整性:雜湊與訊息鑑別碼

保密還不夠。一個讀不懂你訊息的攻擊者,仍可能翻轉位元把它弄壞,或塞進他自己的內容。要逮到這種事,我們需要完整性——一種偵測任何改動的方法。工具就是 密碼雜湊:一個能吃進任意多的資料、產出一段短而固定長度指紋(比如 256 位元)的函數。兩個性質讓它如施了魔法。它是單向的(你無法從指紋反推出原資料),而且具抗碰撞性(你找不到兩筆不同的輸入會產出同一段指紋)。把一份十億位元組的檔案改掉一個逗號,整段指紋就會變得面目全非。

那個祕密,就是把雜湊變成 訊息鑑別碼(MAC)的關鍵。MAC 把訊息連同一把共享祕密金鑰一起雜湊,所以只有握有金鑰的人才能產出有效的標籤。同樣握有金鑰的接收方,會重新計算標籤並檢查是否相符。標準做法是 HMAC,它小心地把金鑰兩度摺進雜湊函數裡,以避開細微的攻擊。一個正確的 MAC 同時證明了兩件事:訊息沒被改過,而且它來自一個知道金鑰的人。注意它同時給了你完整性「與」一種真實性——但僅限於已經共享祕密金鑰的人之間。

真實性:數位簽章

MAC 有個極限:因為驗證用的金鑰跟簽署用的是同一個祕密,任何能檢查 MAC 的人也都能偽造一個。這在兩個互信的夥伴之間沒問題,但拿來向全世界證明「某訊息真的出自你」就毫無用處。為此,我們把公開金鑰密碼學反過來用,得到 數位簽章。要簽署,你用「私鑰」處理訊息的雜湊;要驗證,任何人都用你相配的「公鑰」。只有你能產出這個簽章(私鑰是祕密),但每個人都能檢查它(公鑰是公開的)。

這恰好把加密的圖景翻轉過來。為了保密,你用「接收者」的公鑰上鎖,這樣只有他打得開。為了簽章,你用「自己」的私鑰上鎖,這樣任何人都打得開——而「公鑰打得開」這件事本身,就證明了只有你能鎖上它。實務上你不會簽整份文件;你會先把它雜湊,再簽那段短指紋,這樣更快,也把簽章綁定到那些精確的位元組上。一步步走一遍:

  1. 簽署:寄件方算出訊息的密碼雜湊,再用「自己的私鑰」加密那段雜湊。產出的結果就是簽章,與訊息一起送出。
  2. 驗證第一步:接收方用「寄件方的公鑰」解開簽章,取回寄件方所宣稱的那段雜湊。
  3. 驗證第二步:接收方自己獨立地,對它「實際收到」的訊息算一次雜湊。
  4. 比對:若兩段雜湊相符,則訊息未經竄改「而且」確實來自那把私鑰的持有者。若不符,就拒絕它——某處被動過手腳或遭偽造。

簽章還附帶給你一項 CIA 三要素有時會另外列出的好處:不可否認性。因為只有私鑰持有者才可能簽署,他事後便無法否認自己做過。但請注意第二步裡悄悄藏著一個假設:要驗證,你需要寄件方「真正的」公鑰。你怎麼知道某把公鑰真的屬於你的銀行,而不是屬於那個冒充銀行、把自己的金鑰塞給你的中間人?簽章把信任問題搬了個位置,卻沒把它抹掉。

把它們拼起來,以及密碼學不保證什麼

現在你能看出這些零件如何互相咬合了。公開金鑰密碼學讓陌生人在開放線路上商定一把共享祕密,解決了金鑰分發。那把共享祕密餵給快速的對稱式加密,提供機密性。一個 MAC(或簽章)順道同行,提供完整性與真實性,讓接收方能偵測竄改並確認寄件方。這一整套堆疊,正是 TLS 為了保護 HTTPS 而組裝起來的,也正是為什麼上一篇那個危險的 中間人攻擊,在一條經過加密與鑑別的通道上要難搞得多。

但要誠實面對極限。密碼學保護的是「傳輸中」的訊息;它對「你正在交談的對象是否誠實」、「你連到的伺服器是不是你想連的那一台」隻字未提。最大的未解問題,仍然是那個「真正公鑰」的問題:如何把一把金鑰綁到一個現實世界的身分上。這不是靠更多數學解決的,而是靠憑證與憑證機構——也就是下一篇的信任機制。密碼學同樣救不了你,如果你自己的裝置已被入侵、如果你重複使用一個脆弱的密碼,或如果你只是被騙著把祕密打進一個假網站。

最後一個誠實的提醒,因為它常被過度炒作。量子電腦威脅到今天某些公開金鑰的數學,這就是為什麼人們正在推行後量子演算法。而量子金鑰分發是用物理定律保護一次金鑰交換——但它本身並不加密你的資料,也不會讓密碼學的其餘部分淘汰;你仍然需要對稱加密法、雜湊與簽章。同一個工具箱,更堅固的鎖而已。把這三項工作在腦中理清楚——用金鑰保密、用雜湊與 MAC 守完整、用簽章證真實——你就準備好去看整個網路是如何建立起信任的了。