One Time Pad 密鑰分配
對於多個 OTP 密鑰,為什麼不這樣做:
鍵=雜湊
$$ (EC)DH Shared Secret + Counter $$ 每個消息的計數器都會增加,並且對於每個新的唯一輸入,雜湊的輸出將是隨機的。這種設計有什麼問題或弱點?
編輯:澄清:雙方將擁有來自 ECDH 交換的共享秘密,來自 Pythons os.urandom 的隨機數,用於生成 ECC 密鑰
這個原則很常見,它是從共享秘密中導出的密鑰。學術上要做的是使用密鑰推導函式或使用連接雜湊的 MAC,也許 $$ \operatorname{HMAC-Hash};[;\text{Key}=\text{(EC)DH Shared Secret},,\text{Message}=\text{Counter};] $$
我們將輸出稱為派生密鑰,它可以是一次性密鑰。
我不會稱它為 One Time Pad 密鑰,即使它只使用一次來用 XOR 屏蔽某些有效負載,因為通常的假設是 One Time Pad(密鑰)是真正隨機的,而這只是偽隨機的。
我們將此想法稱為流密碼(將短密碼和計數器擴展為長密碼)的密鑰派生函式(散列 ECDH密碼)。
這個想法沒有問題,也沒有弱點;事實上,它無處不在。 例如,TLS 協議的一部分本質上是這樣工作的:
- 同意 ECDH 秘密 $ s $ .
- 派生會話密鑰 $ k = H(s) $ 通過散列 $ s $ , 在哪裡 $ H $ 是帶有特定標籤的 TLS PRF。
- 為了 $ i^{\mathit{th}} $ 留言,展開 $ k $ 進入每個消息板 $ p_i = H’(k, i) $ , 在哪裡 $ H’ $ 是 ChaCha 或 AES-CTR。
- 加密 $ i^{\mathit{th}} $ 資訊 $ m_i $ 與密文 $ c_i = m_i \oplus p_i $ .
- (也驗證密文 $ k $ 和 $ i $ ,因為防止偽造實際上總是至少與保守秘密一樣重要。)
當然,安全性僅與 ECDH 系統、KDF 和流密碼的安全性一樣好——如果使用 32 位管道和 RC4 作為流密碼的微小曲線和散列函式,它就贏了不能提供太多安全保障。
但是,如果您使用 HKDF-SHA256 之類的合理選擇來散列 X25519 ECDH 機密並使用 ChaCha/Poly1305 加密和驗證消息,那麼您會沒事的——您不會因為這種結構而出現任何安全問題。您甚至可以使用 HKDF-SHA256 直接將秘密擴展為一個長墊,而無需 ChaCha(但它不會很快)。
PS 有一個有趣的社會現象,在這種情況下你不能說“一次性便箋”。出於某種原因,“一次性墊”一詞僅適用於理想模型 $ c_i = m_i \oplus p_i $ 當。。。的時候 $ p_i $ 是完全均勻分佈的,或者用於該模型的歷史使用(無論歷史上可能有偏見或重複使用墊) - 當您在現代密碼學中使用該模型時,就像您剛剛描述的那樣,這是絕對不允許的 $ p_i $ 選擇作為密鑰的偽隨機函式,儘管流密碼的現代概念顯然受到一次性密碼模型的安全性的啟發和證明。
只有“一次性便箋簿”一詞是這樣工作的;當密碼學家研究一個理想化的模型時,沒有人會注意到 $ f(\cdots f(f(\mathit{iv}, m_1), m_2) \cdots, m_n) $ 對於均勻隨機 $ f $ 然後實例化它 $ f = \operatorname{AES}_k $ 但將理想化模型和實例化都稱為“CBC”——僅禁止將理想化模型稱為 $ c = m \oplus p $ 實例化 $ p = \operatorname{AES}_k(0) $ 一個“一次性墊”。也許是因為曲柄被像一次性墊模型的技術屬性“完美保密”這樣充滿價值的名稱所吸引,所以對一次性墊的痴迷是曲柄的有用指標。