KCV 和與分組密碼操作模式的兼容性
最近有一個關於 KCV(密鑰檢查值)的問題,該值由許多 CRYPTOKI (PKCS#11) 實現提供。我不是特別喜歡 KCV,但我決定問一下如何正確使用 KCV。
此“KCV”(也稱為 CKA_CHECK_VALUE 對象屬性)值派生如下:
- 對於大多數對象:對象的 SHA-1 雜湊的前三個字節。
- 對於塊密碼的加密密鑰,它是由 ECB 模式加密一個全零的塊產生的密文的前三個八位字節。
很少使用密文發送 KCV(密鑰檢查值),因為檢查並不能很好地確保密鑰的正確性。poncho 對此問題的出色回答Sending KCV (key check value) with cipher text說明了幾個原因。
我擔心的是,KCV 可能會危及正確使用某些操作模式的機密性或真實性:
- CMAC 模式使用 $ k_{0} = E_{k}(0^{128}) $ 用於派生子密鑰。
- 如果從計數器值 0 開始使用 CTR 模式,那顯然允許顯示三個前字節。
在上述情況下避免使用 KCV 是個好主意嗎?
是否還有其他一些操作模式,其中揭示零塊加密的前八位字節是不好的?
我對此想了很多,我認為總的來說答案是否定的,在這種情況下使用 KCV 不是一個好主意。當需要 KCV 時,使用雜湊甚至更好的 MAC(使用密鑰作為 MAC 密鑰)將是一個更好的主意。與零相比,使用以前隨機(塊)字節可能對攻擊者沒有用處會更好。
您當然可能想知道是否應將所有零輸入用於 CMAC 和計數器模式。對於 CMAC 來說,使用另一個常數值會很容易。對於 CTR 模式,最好總是在使用之前增加計數器;一種方法是簡單地從值 1 開始。以這種方式定義一個指定 nonce / IV / 計數器的協議很容易。
將 KCV 用於密鑰對於密鑰管理非常有用 - 它確實為我工作的公司節省了很多時間。
對於 CMAC 模式,很容易顯示 KCV 返回部分或全部密鑰…
- 計算臨時值 $ k_0 $ = $ \operatorname{E}(k,0) $ .
- 如果 $ \operatorname{msb}(k_0) = 0 $ , 然後 $ k_1 = k_0 \ll 1 $ , 別的 $ k_1 = (k_0 \ll 1) \oplus C $ .
- 如果 $ \operatorname{msb}(k_1) = 0 $ , 然後 $ k_2 = k_1 \ll 1 $ , 別的 $ k_2 = (k1 \ll 1) \oplus C $ .
- 返回鍵 $ k_1 $ 和 $ k_2 $ 用於 MAC 生成過程。
這些密鑰依次用於作為 CBC-MAC 基礎的 CBC 模式加密的最後一個塊,該塊用於建構 CMAC。現在看來,這會在加密之前向攻擊者透露最後一個塊。
現在是棘手的部分,我不確定這是否會否定添加到 CBC-MAC 以創建 CMAC 的安全性,但它看起來並不好。
至於 CTR 模式,很明顯,如果您將 nonce(和計數器)設置為全零,則可以直接解密(部分)密文的第一個塊。沒有比這更直接的攻擊了。