流密碼如何一次加密一位並且仍然安全?
我正在閱讀流密碼和分組密碼之間的區別,注意到分組密碼,一次加密的 64 位左右的塊。但是,流密碼一次加密 1 位,對我來說似乎很容易反轉?如果流密碼的算法沒有改變,那麼是什麼阻止對手輕鬆解密流密碼生成的密文呢?
TL; DR 那個位依賴於一個大狀態和許多無法輕易逆轉的計算,正如您似乎相信的那樣。
流密碼創建依賴於輸入密鑰材料(密鑰種子)的密鑰流。儘管流密碼一次輸出一位(出於顯而易見的原因,在實現中通常一次輸出一個字節),但這並不意味著內部狀態具有該大小。內部狀態通常會大於密碼的安全強度。
在輸出單個位之前,必須更新狀態,以使輸出無法區分隨機輸出和敵手輸出。有時,如果流密碼(部分)被破壞,情況並非完全如此:RC4 的初始輸出流與隨機流是可區分的;需要首先刪除密鑰流的頭部以創建一個相對安全的密碼。
對手不可能計算狀態的任何重要部分或密鑰的任何部分。
要使用流密碼,每個加密的密鑰/隨機數組合保持唯一非常重要。如果不是這種情況,那麼可以從使用相同組合加密的消息中檢索到很多資訊。
簡而言之,流密碼使用加密安全偽隨機數生成器 (CSPRNG) 生成任意長度的密鑰流,然後使用生成的偽隨機資訊通過組合兩者來加密明文。
建構的安全性基本上依賴於 CSPRNG 的輸出是不可預測的。
消息的長度與隨機數的生成無關:CSPRNG 的設計具有足夠的狀態大小和復雜性,以確保未來的輸出仍然不可預測,無論過去可能擁有多少輸出。
例如,Salsa20每次呼叫函式都會輸出 512 位隨機資訊。如果您的消息只有 1 位長,那麼您只需使用輸出的第一位並丟棄未使用的位。
但是,流密碼一次加密 1 位,對我來說似乎很容易反轉?
在不知道 CSPRNG 生成的密鑰流是什麼的情況下,僅給定 CSPRNG 的密文和初始化向量/種子,單個比特(或任意數量的比特)的加密是不容易可逆的。
撤消該操作的唯一方法是生成相同的密鑰流,然後從密文中去除隨機資訊。CSPRNG 是帶密鑰的,它需要密鑰來生成密鑰流。
如果流密碼的算法沒有改變,那麼是什麼阻止對手輕鬆解密流密碼生成的密文呢?
目前尚不清楚“流密碼的算法沒有改變”是什麼意思。我猜這意味著“流密碼總是輸出相同的密鑰流”。
只要使用唯一的種子來加密每條消息,生成的密鑰流將是唯一且不可預測的。
如果相同的種子被重複用於多個消息,那麼攻擊者可以(可能/可能)從已知的明文/密文對中恢復一些密鑰流,然後使用恢復的密鑰流來解密其他密文。
出於這些原因,為每條消息使用唯一的種子是標準做法。
免責聲明:為了簡化解釋,省略了詳細資訊,即假設 CSPRNG 是安全的,沒有提及成功的機率等…