鑑別式密碼(authenticated ciphers)是「密碼 + MAC 組合」的替代方案。它們像一般密碼,只是除了密文之外還回傳一個鑑別標籤:
AE(K, P) = (C, T) 鑑別式加密
AD(K, C, T) = P 鑑別式解密單一個鑑別式密碼演算法做完了「密碼 + MAC 組合」的工作,因而更簡單、更快,往往也更安全。
若 C 或 T(或兩者)無效,AD 會回傳錯誤,以防止收件者處理可能被偽造的明文。反之,若 AD 回傳了明文,你就能確定它是由知道秘密金鑰的人或物加密的。
安全需求#
鑑別式密碼的基本安全需求很簡單:它的鑑別強度應該與 MAC 相當——也就是說,應該不可能偽造出一組會被解密函式 AD 接受並解密的 (C, T) 對。
至於機密性,鑑別式密碼在本質上比基本密碼更強:持有秘密金鑰的系統只有在鑑別標籤有效時才會解密密文,標籤無效則明文被丟棄。
這個特性阻止了攻擊者執行選擇密文查詢——那種「造出密文並索取對應明文」的攻擊。
帶關聯資料的鑑別式加密(AEAD)#
密碼學家把關聯資料(associated data)定義為:由鑑別式密碼處理、被鑑別(因為有鑑別標籤)但不被加密的任何資料。
預設情況下,所有餵給鑑別式密碼的明文資料都會被加密與鑑別。但如果你只想鑑別整則訊息(包含它未加密的部分),卻不想加密整則訊息呢?
典型情境:密碼要處理一個由標頭加載荷組成的網路封包。
- 你想加密載荷以隱藏實際傳輸的資料。
- 但不加密標頭,因為它含有把封包送達最終收件者所需的資訊。
- 同時你仍想鑑別標頭的資料,以確保它來自預期的寄件者。
為此,密碼學家創造了 AEAD(authenticated encryption with associated data)。AEAD 演算法讓你把明碼資料附在密文上,方式是:若明碼資料被破壞,鑑別標籤就不會通過驗證,密文也不會被解密。
AEAD(K, P, A) = (C, A, T) 加密
ADAD(K, C, A, T) = (P, A) 解密- 未加密的關聯資料
A維持不變。 - 密文是明文的加密。
- 鑑別標籤同時依賴
P與A,只有在C與A都未被修改時才會通過驗證。
使用 AEAD 時值得注意的一點:你可以讓
A或P為空。
- 若關聯資料
A為空,AEAD 就退化成一般的鑑別式密碼。- 若
P為空,它就只是一個 MAC。
本書寫作時,AEAD 是鑑別式加密的現行常規。由於今日幾乎所有使用中的鑑別式密碼都支援關聯資料,本書提到「鑑別式密碼」時除非另有說明,指的都是 AEAD。
用 nonce 避免可預測性#
回想第 1 章:加密方案要安全,就必須不可預測——對同一段明文重複呼叫時要回傳不同的密文,否則攻擊者能判斷同一段明文是否被加密了兩次。
為了不可預測,區塊密碼與串流密碼會餵給密碼一個額外參數:初始值(IV)或 nonce。鑑別式密碼用同樣的技巧:
AE(K, P, A, N) = (C, T)
AD(K, C, A, T, N) = (P, A)與區塊密碼、串流密碼一樣,鑑別式密碼的解密需要加密時所用的 nonce 才能正確運作。
什麼是好的鑑別式密碼#
研究者自 2000 年代初就在努力定義「什麼構成一個好的鑑別式密碼」,本書寫作時答案仍然難以捉摸。由於 AEAD 有許多扮演不同角色的輸入,要定義安全概念比只加密訊息的基本密碼更難。
以下歸納評估鑑別式密碼時最重要的準則。
安全準則#
最重要的準則是它保護資料機密性(明文的秘密性)與通訊真確性與完整性(如同 MAC 偵測受損訊息的能力)的能力。
鑑別式密碼必須在兩個聯盟中同時競爭:它的機密性必須與最強的密碼一樣強,它的真確性必須與最好的 MAC 一樣強。
換句話說:把 AEAD 的鑑別部分拿掉,你應該得到一個安全的密碼;把加密部分拿掉,你應該得到一個強的 MAC。
另一個更微妙的準則是面對重複 nonce 時的脆弱性:若一個 nonce 被重複使用,攻擊者能解密密文嗎?能學到明文之間的差異嗎?
研究者把這個穩健性概念稱為抗誤用性(misuse resistance),並設計了抗誤用的鑑別式密碼,來衡量重複 nonce 的衝擊——判斷這種攻擊下機密性、真確性或兩者是否會被危及,以及關於加密資料的哪些資訊可能會外洩。
效能準則#
與所有密碼演算法一樣,鑑別式密碼的吞吐量可以用每秒處理的位元數衡量。這個速度取決於密碼演算法所執行的運算數,以及鑑別功能的額外成本。
如你所料,鑑別式密碼額外的安全特性是有效能代價的。
但效能不只關乎純速度,還包括三件事:
可平行性(parallelizability):能否同時處理多個資料區塊,而不必等前一個區塊處理完。基於區塊密碼的設計,在每個區塊都能獨立處理時就容易平行化。例如 CTR 模式可平行化,而 CBC 加密模式不行(因為區塊被鏈接起來)。
內部結構:分成單層與雙層兩種。在雙層結構中(例如廣泛使用的 AES-GCM),一個演算法處理明文,第二個演算法再處理其結果——通常第一層是加密層、第二層是鑑別層。雙層結構讓實作更複雜,也傾向於拖慢運算。
可串流性(streamable,也稱 online cipher):能逐區塊處理訊息並丟棄已處理的區塊。相對地,不可串流的密碼必須儲存整則訊息,通常是因為它們需要對資料連續走兩趟:一趟從頭到尾,另一趟從第一趟所得資料的尾端走回開頭。
由於記憶體需求可能很高,某些應用無法使用不可串流的密碼。
例如路由器可以收到一個加密資料區塊、解密它、回傳明文區塊,再繼續解密訊息的下一個區塊——不過解密訊息的接收者仍必須驗證資料流末端送來的鑑別標籤。
功能準則#
功能準則是密碼或其實作中與安全性、效能都沒有直接關係的特性:
關聯資料的位置:某些鑑別式密碼只允許關聯資料先於待加密資料(因為它們需要先存取它才能開始加密),另一些要求關聯資料後於待加密資料,還有些支援關聯資料放在任何位置——甚至夾在明文片段之間。
最後這種最好,因為它讓使用者能在任何可能的情境下保護資料。但它也最難安全地設計:一如往常,更多功能往往帶來更多複雜度——以及更多潛在漏洞。
加解密能否共用核心演算法:許多鑑別式密碼基於 AES 區塊密碼,而 AES 規定了兩個相似但不同的演算法來加解密一個區塊。CBC 模式需要兩者,CTR 模式則只需要加密演算法。
同時實作加密與解密演算法的額外成本,對多數軟體沒有影響,但在低成本專用硬體上往往很明顯——那裡的實作成本是以邏輯閘、或密碼學所佔的矽面積來衡量的。