鑑別式密碼(authenticated ciphers)是「密碼 + MAC 組合」的替代方案。它們像一般密碼,只是除了密文之外還回傳一個鑑別標籤

AE(K, P) = (C, T)          鑑別式加密
AD(K, C, T) = P            鑑別式解密

單一個鑑別式密碼演算法做完了「密碼 + MAC 組合」的工作,因而更簡單、更快,往往也更安全

CT(或兩者)無效,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 維持不變。
  • 密文是明文的加密。
  • 鑑別標籤同時依賴 PA,只有在 CA 都未被修改時才會通過驗證。

使用 AEAD 時值得注意的一點:你可以讓 AP 為空。

  • 若關聯資料 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 模式則只需要加密演算法。

    同時實作加密與解密演算法的額外成本,對多數軟體沒有影響,但在低成本專用硬體上往往很明顯——那裡的實作成本是以邏輯閘、或密碼學所佔的矽面積來衡量的。