無連接UDP加密通信中的重放攻擊防範
當兩方交換 UDP 消息時,有哪些選項可以防止重放攻擊。沒有建立連接或會話。通信方具有用於加密 (aes-256) 和身份驗證 (hmac-sha-256) 的預共享密鑰。
通訊設備:
- 沒有實時時鐘。實時可以從 NTP 獲得,(但是 NTP 的安全性呢?)
- 擁有永久記憶
- UDP 通信是唯一的選擇
處理重放攻擊預防的最簡單方法(在某種狹義上,目標是避免接收器允許對其多次播放相同的命令)是在數據包,在形成要發送的數據包之前由發送方遞增。接收端檢查數據包的真實性,丟棄計數器欄位小於或等於自己計數器的數據包,然後將自己的計數器設置為剛剛收到的計數器;最初,計數器兩邊都為零;它必須足夠大以至於不能溢出,通常 4 個字節就足夠了。
問題是:
- 這可以防止被動竊聽材料的重放,但不會延遲主動竊聽和抑製材料的播放。在許多對抗模型中,這是一個毀滅性的問題。想像一個車庫開門器:對手攔截“開門”命令,指望使用者重新發出另一個命令,也攔截該命令,向車庫門發出第一個命令,門打開,使用者滿意;當使用者離開時,對手稍後會播放第二個命令。在數據包末尾帶有 CRC 的無線電鏈路上,可以通過乾擾 CRC 的末尾來進行攻擊,以便接收器忽略數據包,但竊聽者擁有數據,可能具有相當數量的錯誤檢測能力.
- 這需要發送方和接收方中的可靠原子計數器,這很難,尤其是在攻擊者可以在精確定時更新計數器的瞬間切斷發送方或接收方的電源的情況下。即使是攻擊者無法觸及的帶有電池/超級電容備份的靜態 RAM 也不能提供超出 wordsize 的原子更新(然後,並非所有人都這樣做,更不用說他們這樣做了);EEPROM 和 Flash 的情況更糟,它們的擦除次數通常比計數器的範圍要少,並且可以進入亞穩態,讀取的值變得不可靠。這可以解決,但眾所周知很難解決。
- 每個發送者的接收者中必須有一個不同的計數器(可以在發送者端使用單個計數器)。
- UDP 可能發生的數據包亂序傳送不再起作用。這可以通過一個滑動視窗來解決,通常在 RAM 中,但會增加複雜性(因此存在錯誤風險;一些在以下早期版本中短暫出現)。
每條評論添加:接收者維護一個點陣圖 $ b $ 位,最多 $ b $ 過去的計數器值小於它願意接受的目前計數器;RAM 中的點陣圖在復位時被初始化為全零;而如果 $ 0\le j<b $ , 和位 $ j $ 點陣圖中為 1,接收方的計數器為 $ c $ , 和 $ c>j $ ,然後是具有計數器欄位的數據包 $ c-j-1 $ 將被接受(當它根據本答案第一段中的規則被拒絕時),並且位 $ j $ 在點陣圖中將變為零。接收方接收數據包的工作變成
檢查數據包的大小和完整性
提取計數器欄位 $ x $ 數據包的
如果 $ x>c $
- 如果 $ x-c>b $ ,將點陣圖設置為全1;否則移動點陣圖,在索引 0 處引入一個零位,然後 $ x-c-1 $ 次(可能為零)移動點陣圖,在索引 0 處引入一位。在 C 或 C++ 中,使用 $ b=32 $ 並將
m
點陣圖作為uint32_t
,這整個步驟可能是:m = (x-c>32) ? 0xFFFFFFFF : ((m+m+1)<<(x-c-1))-1;
- $ c\gets x $ 原子地
- 接受按順序接收的數據包(當點陣圖全為零時,以後可能不會接受較早的數據包),完成;
否則,如果 $ 0<c-x\le b $ 如果(現在定義明確的)位 $ c-x-1 $ 點陣圖是一個
- 將所述位更改為零
- 接受亂序接收的數據包(可能需要特別注意),完成;
否則,拒絕數據包。
如 (1) 中所述,對於能夠延遲數據包並從中獲益的主動攻擊者,上述所有內容都是不安全的。在這種情況下安全且不需要困難的原子計數器的替代方案包括在 UDP 之上建構質詢/響應協議,質詢適用於接收器測量的特定延遲(這需要能夠評估經過的時間) ,但不是絕對時間);主要問題是,這需要雙向通信。
也可以使用經過驗證的絕對時間源;難的是找到一個可靠的免費的,看這個。