訊息鑑別碼(message authentication code)
想像你和朋友共用一個秘密詞。在送出任何紙條前,你按約好的方式把這個秘密詞攪進紙條的文字裡,再把結果蓋成一個短短的標籤印在底部。知道秘密詞的朋友能從收到的紙條重算出標籤、檢查是否相符。改動紙條的攻擊者做不出相符的標籤——他不知道秘密詞。訊息鑑別碼(MAC)正是如此:一個從訊息與共享秘密金鑰算出的短標籤,證明訊息未被竄改、且來自一個知道金鑰的人。
它修補了純雜湊的弱點。裸雜湊能偵測意外的改動,卻擋不了刻意的攻擊者——他可以直接編輯訊息再重算雜湊。MAC 把一把秘密金鑰混入計算,於是只有持有金鑰的人才能做出有效的標籤。最常見的構造是 HMAC,它以一種特定而安全的方式,把像 SHA-256 這樣的密碼雜湊與秘密金鑰結合起來(HMAC-SHA256)。送出時:計算 tag = HMAC(金鑰, 訊息),送出訊息加標籤。驗證時:用收到的訊息與你的金鑰重算標籤,只有相符才接受。對訊息的任何改動、或任何沒有金鑰的人,都過不了這道檢查。
為什麼重要:MAC 同時帶來完整性與鑑別,既便宜又快,而且無所不在——TLS 在每一筆記錄上都用 MAC(或內含 MAC 的鑑別加密模式),讓被竄改或注入的資料被拒收。誠實的限制是:MAC 用的是共享秘密,所以它無法向第三方證明訊息由誰送出——發送者與接收者持有同一把金鑰,任一方都可能做出那個標籤。這正是數位簽章不同之處:它用的是只有發送者才有的私鑰,提供了 MAC 給不了的不可否認性。
一個 API 請求送出主體外加 tag = HMAC-SHA256(共享金鑰, 主體)。伺服器用同一把金鑰,從它收到的主體重算標籤。如果某個代理翻轉了主體的一個位元組,重算出的標籤就不會相符,伺服器便拒絕該請求——竄改被抓到了。
一個帶金鑰的標籤:只有持金鑰者能做、任何有金鑰者能驗。
MAC 能證明完整性、以及發送者知道金鑰,卻無法證明是兩個金鑰持有者中的哪一個送的——所以它不提供不可否認性。要做到那點,你需要數位簽章,它用的是只有發送者單獨持有的私鑰。