Encryption

使用時間戳來建構 nonce 是否安全?

  • August 7, 2018

我正在編寫一個應用程序,它可以在多個客戶端上使用,並在伺服器上共享數據。為確保數據永遠不會讓客戶端未加密,應用程序應使用 AES-GCM 和 ChaCha20-Poly1305 提供加密。它們都需要一個 96 位的 nonce,建議使用一個計數器,以確保這個 key 的 nonce 永遠不會重複。

由於我想不出一個可靠的系統來保證這個 nonce 的唯一性/狀態(伺服器是被動的並且只提供儲存),我考慮使用時間戳來建構 nonce:

Nonce-96-bit = Timestamp-Milliseconds-64bit combined_with CsRandom-Number-32bit

這是解決問題的正確方法嗎?我知道 XChaCha20-Poly1305 可以用更大的隨機數解決問題,因此可以使用隨機數,但目前我正在使用 BouncyCastle 庫,它提供了必要的 .Net 跨平台支持。

這不是一個好主意——你發生衝突的機會並不低(取決於你擁有的客戶數量)。充其量,你的機會是 $ 2^{-32} $ 2個活躍客戶。您最好使用NIST AES-GCM 指南推薦的安全隨機 96 位隨機數(請注意,您不能發送超過 $ 2^{32} $ 使用此構造時具有相同密鑰的消息,以便 IV 碰撞的機會不超過 $ 2^{-32} $ )

我要說的第一點是:為什麼不能只使用 TLS?(或者如果它是非互動式協議,為什麼不能使用 ECIES?)

Nonce-96-bit = Timestamp-Milliseconds-64bit combined_with CsRandom-Number-32bit

我的印像是,這可能比隨機的 96 位 nonce 更容易被 nonce 重用。所需要的只是使用相同的密鑰、相同的時間戳值以及隨機值的 32 位衝突發送兩條消息( $ 2^{-32} $ 機會)。如果不深入了解您的應用程序在生產中的使用方式,就不可能計算出您看到時間戳衝突的頻率,但根據我的經驗,這種衝突的發生率確實比 96 位隨機數衝突更常見。

避開整個問題的一種方法是使用臨時會話密鑰(正如 TLS 和 ECIES 已經為您所做的那樣,提示提示)。這樣您就可以使用計數器隨機數,因為會話的範圍僅限於易失性記憶體的生命週期,從而避免了對持久狀態的需要。如果您堅持建構自己的協議,您可以嘗試僅使用共享主密鑰來加密隨機會話密鑰;在這種情況下,隨機 96 位 nonce 衝突的風險因明文是隨機的這一事實而得到緩解。

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