Rc4

這 2 個 KSA 捷徑會削弱 RC4 嗎?

  • June 5, 2012

Alice 安全地給 Bob 一個密鑰,這樣他們就可以交換 10 條用 RC4 加密的不同消息。(消息將包括一個唯一性計數器和一個用於身份驗證的 MAC。)對於每個消息交換,Alice 和 Bob 都首先使用密鑰(即“KSA”密鑰調度算法,根據維基百科)置換標準字節數組:

for i from 0 to 255
   S[i] := i
endfor
j := 0
for i from 0 to 255
   j := (j + S[i] + key[i mod keylength]) mod 256
   swap values of S[i] and S[j]
endfor

此時,Alice 和 Bob 各自計算出相同的 S

$$ $$數組,並且後續 RC4 步驟不再使用密鑰。 捷徑 1: Alice 決定不再安全地向 Bob 發送密鑰並讓他為每次消息交換執行 KSA 步驟,而是計算 S

$$ $$數組,安全地將 256 字節數組而不是密鑰發送給他,從那時起,每次他們需要加密/解密時,他們都將跳過 KSA 步驟以節省時間,並從 Alice 預先計算的 S 開始$$ $$大批。 捷徑2: 使用上述算法計算初始S後

$$ $$她計劃發送給 Bob 的數組而不是密鑰,Alice 意識到 KSA 步驟似乎基本上只是想打亂 S$$ $$大批。因此,她沒有根據密鑰對數組進行加擾,而是依靠作業系統的 random() 函式並僅計算…

for i from 0 to 255
   S[i] := i
endfor
for i from 0 to 255
   swap(S[i], S[random(0..255)]) // swap S[i] with some arbitrary S[]
endfor

…並安全地將她的“隨機”加擾數組發送給 Bob,該數組甚至不使用密鑰。

這兩條捷徑會削弱 RC4 嗎?

關於#1:

關於算法本身,您不會失去任何東西。從密鑰到密鑰調度 (KS) 的算法是確定性且眾所周知的,因此任何獲得密鑰的人也可以輕鬆獲得 KS。通過傳遞 KS 而不是密鑰,實際算法本身並沒有降低安全性。

但是,依靠 KS 而不是密鑰會使事情變得更加困難。

您描述的方案不安全,因為加密不是隨機的。所有對稱密鑰加密都需要隨機化。您在輸出中包含一個唯一的計數器,並且該計數器的一些變體適用於分組密碼,但這不會隨機化您的流密碼的整個密文。對於流密碼,隨機化作為唯一的隨機數發生,該隨機數與密鑰組合以生成唯一的密鑰流,該密鑰流又用於創建唯一的密文。

可以通過在每次加密的密鑰中添加隨機數來確保您的方案安全。因此,在這種情況下,交換 KS 本身實際上會使使用良好的加密變得更加困難,因為您不能簡單地交換一個新的 nonce 來進行加密,您必須交換一個全新的 KS 以包含來自 nonce 的更改。nonce 可以公開交換且較短,但 KS 必須保密且較長。那麼問題就變成了,您如何安全地交換更新的 KS?您可能能夠安全地同意第一個密鑰,但您能否不斷地安全地同意新密鑰?當原始密鑰達成一致時,您是否必須提前設置所有 KS?它變得混亂。

如果您嘗試優化加密,標準的做法是交換密鑰,然後在所有使用它的客戶端上記憶體 KS。您必須為每個客戶端計算一次 KS,但 RC4 KS 確實很短,在任何半現代平台上都不應該是速度問題。(兩個 256 的循環,平均大約三個記憶體查找和每個循環的一些添加。作為一次性性能損失會有多糟糕?)這樣優化在每個客戶端中抽像出來,你仍然有正常的密鑰交換功能。

因此,對於您的方案,您不應該為每條消息重新開始加密,除非您想為每次重置包含唯一的隨機數。為避免出現隨機數,您可以繼續使用 RC4 的持續輸出流來處理所有消息(以某種方式確保每個客戶端同步到流中的距離)。無論哪種方式都會比目前的方案更好。

我知道其中大部分與您的問題沒有直接關係,但即使您的提議本質上並不更不安全,它確實使修復您的不安全協議更加困難。

關於#2:

請注意,基本上,您更換了

j := (j + S[i] + key[i mod keylength]) mod 256

j := random(0..255)

暫時假設為keylength256。現在考慮來自高質量熵源的情況,即key實際上只是一個隨機的 256 字節字元串,其質量與 256 字節會產生的質量相同。從 S 中添加常量和一些輕微的“自我修改”random()``key``random()

$$ i $$不會提高質量key。所以對於一個好的 256 字節隨機密鑰,你的方案沒有改變任何東西。事實上,您可以計算新方案將創建的有效密鑰:

for i from 0 to 255
   S[i] := i
endfor
j := 0
for i from 0 to 255
   temp = random(0..255)
   k[i] := temp - j - S[i]
   j = temp
   swap(S[i], S[j])
endfor

也就是說,k這裡的密鑰將產生與您的方案相同的 KS(如果從 給出相同的值random())。這個計算出來的密鑰仍然與random(). 因此,您無需預先生成要使用的密鑰,而是動態生成它。真的沒有什麼區別。

(如果 和 的回饋式角色jS[i]您有關,請記住我們假設這random()是一個很好的熵源。這些變數充其量是在 的輸出中添加一個隨機值random(),但該輸出已經是安全隨機的,因此沒有添加質量或刪除。最壞的情況是他們添加了常量值,而且它也不會改變任何東西。)

所以你的第二個方案相當於只生成一個 256 字節的隨機密鑰,這是 RC4 可以使用的最佳密鑰。鑑於您的方案沒有改進 RC4 的最大安全範圍,它並沒有真正添加任何東西。您可以通過選擇適當的強鍵來選擇 KS 的質量。如果您想要最大的安全性,只需生成一個高質量(256 字節)的密鑰。(可能通過呼叫random(),如果您相信它會生成密鑰。)

筆記:

這裡的所有內容都假設您可以安全地分發初始密鑰並且您信任此random()函式的輸出。似乎您確實假設了這一點,但請記住,這是兩個非常大的假設。確保您的random()呼叫是加密安全呼叫,最好是CryptGenRandom()在 Windows 或/dev/random*nix 上。

引用自:https://crypto.stackexchange.com/questions/2802