Security

為什麼閃電網路上傳輸消息的長度是加密的?

  • March 12, 2019

從 BOLT 08 中我們可以看到,每條消息都是通過以下方式發送的:

2 byte: length
16 byte: MAC 
[length] byte: Encrypted message
16 byte: MAC 

實際上,這些消息將通過 Internet 上的 TCP/IP 發送。ip 標頭指定正在發送的數據包的長度。如果我們提取長度並減去標頭的 34 字節加上兩個 MAC,我們將知道消息有多長。

總是發送一個 2^16 字節的 ip 包並用垃圾數據填充其餘部分的想法是什麼?如果是,為什麼沒有在 BOLT 中指定?如果不是:為什麼還要加密長度?

我假設攻擊者能夠跟踪閃電埠上的所有 tcp/ip 包,並且至少能夠推斷出正在發送的消息,即使消息本身是安全的。

假設確實可以推斷出消息長度,那不能與 MAC 一起使用來重建該消息的會話密鑰嗎?

TCP 和其他基於流的協議在應用程序級消息和 IP 數據包之間沒有一對一的關聯。如果您呼叫send()3 次,可能會導致通過線路發送單個 IP 數據包(例如,由於預設啟用的 Nagle 算法),它可能會作為 3 個數據包單獨發送,正如您對面向數據包的協議所期望的那樣像 UDP,或者消息可能最終被分成幾個數據包,因為 IP 層有一個 MTU。

它通常在應用層是不受您控制的。因此,您不能依靠從 IP 標頭中讀取長度來告訴您消息的長度。您需要將長度編碼到數據流中,並將從流中傳入的數據重建為協議所理解的單個消息。

在 BOLT#8 規範中單獨對長度進行編碼的原因是,每條消息都必須作為單個操作進行解密,因為每次解密都必須增加 ChaChaPoly 密碼中使用的計數器。在對加密的有效負載呼叫解密函式之前,您需要知道消息的確切長度。

在 BOLT#8 協議中,您發送加密消息 + MAC 的確切長度,不添加任何填充。接收者應首先顯式呼叫recv(buffer, 18, ...),解密結果以獲得msg_len,然後呼叫recv(buffer, msg_len, ...)以檢索加密消息,然後可以將其完整解密。recv也可能返回比請求更少的字節,因此在這兩種情況下,都recv必須檢查結果,如果讀取的長度小於預期長度,recv則應使用剩餘的預期長度再次呼叫。

引用自:https://bitcoin.stackexchange.com/questions/85259