Encryption

你能解釋一下 Bleichenbacher 對 PKCS#1 v1.5 的 CCA 攻擊嗎?

  • July 27, 2015

我研究了 Bleichenbacher 對 PKCS#1 v1.5 的 CCA 攻擊。是該地區許多版本攻擊的基地。

我試圖理解這種攻擊,但我看到的每一個解釋都是從技術細節開始的,沒有給出一些概述,所以很難理解……

在給出小細節之前,你能用簡單的話解釋一下嗎?

當使用 RSA加密某些東西時,使用 PKCS#1 v1.5,首先**填充要加密的數據,然後將填充的值轉換為整數,並應用 RSA 模冪運算(使用公共指數)。解密後,應用模冪(使用私有指數),然後刪除填充。Bleichenbacher 攻擊的核心依賴於預言機:如果某個系統在某處可以判斷,給定加密消息長度的字節序列,解密是否會產生具有適當填充格式的東西或不是。

一個例子是 SSL/TLS 伺服器。在最初的握手中,在某些時候,客戶端應該生成一個隨機密鑰(“pre-master secret”),用伺服器的公鑰加密它,然後發送它。伺服器解密該值,獲得預主密鑰,然後從該預主密鑰計算用於對其餘連接進行對稱加密的密鑰。使用該標准進行指導,客戶端發送一個ClientKeyExchange(其中包含加密的預主密鑰),然後是 a ChangeCipherSpec,然後是Finished; 最後一條消息使用派生的對稱密鑰加密,其內容由伺服器驗證。

如果客戶端向伺服器發送正確長度的隨機字節序列而不是正確加密的預主密鑰,那麼伺服器將在大多數情況下以錯誤消息響應,告訴您“我試圖解密您的ClientKeyExchange內容,但這失敗了,其中沒有適當的填充”。然而,純偶然的情況下,隨機字元串可能會在應用模冪運算後產生一些看起來像具有正確填充的預主密鑰的東西。在這種情況下,伺服器不會抱怨ClientKeyExchange,而是抱怨Finished消息,該消息將被錯誤地加密。

這是攻擊者想要的資訊:他發送的字節序列在解密後是否看起來正確填充。


讓我們看看更多的技術細節。在 RSA 中,讓 $ n $ 是公共模數。讓 $ M $ 成為要加密的消息 $ n $ (在 SSL 的情況下, $ M $ 是前主密鑰,長度為 48 字節)。用於加密的 PKCS#1 v1.5 填充包括在左側添加一些字節,以便填充後的總長度等於 $ n $ . 例如,如果伺服器的公鑰是 2048 位 RSA 密鑰,那麼 $ n $ 長度為 256 字節,所以填充 $ M $ 長度也應該是 256 字節。

正確填充的消息 $ M $ 具有以下格式:

0x00 0x02 [some non-zero bytes] 0x00 [here goes M]

所以字節序列將從一個值為 0 的字節開始,然後是一個值為 2 的字節,然後是一些應該具有隨機值(但不是零)的字節,然後是一個值為 0 的字節,然後 $ M $ 本身。調整非零字節數,使總長度等於 $ n $ . 解密後,伺服器將查看前兩個字節,並要求它們按順序等於 0x00 和 0x02。然後它將掃描值為 0 的下一個字節,從而跳過所有隨機的非零字節。這樣,可以明確地刪除填充。

因此,如果客戶端發送一個隨機的字節串,那麼它的機率大致在 $ 2^{-15} $ 和 $ 2^{-17} $ 遵循 PKCS#1 填充格式(即前兩個字節為 0x00 0x02,之後至少有一個字節值為 0 的機率;確切的機率取決於 $ n $ ).

攻擊場景如下:

  • 有一個 SSL 伺服器,它將根據是否找到正確的 PKCS#1 填充來發送不同的錯誤消息。或者,這兩種情況可以通過其他一些資訊洩漏來區分(例如,如果填充正確,伺服器需要更長的時間來響應)。
  • 攻擊者竊聽了一個連接,並希望對其進行解密。他觀察到了ClientKeyExchange,所以他看到了一條加密資訊 $ c $ . 他知道 $ c = m^e \pmod n $ 在哪裡 $ e $ 是公共指數,並且 $ m $ 是該連接的填充前主密鑰。他想康復 $ m $ ,或至少包含在 $ m $ ,因為這將允許他計算用於連接的對稱密鑰。

然後攻擊者將啟動到伺服器的許多連接。對於每個連接,攻擊者都會生成一個值 $ s $ 並發送ClientKeyExchange一個值 $ c’ = cs^e \pmod n $ . 伺服器解密,並獲得 $ m’ = (cs^e)^d \pmod n $ ( $ d $ 是私有指數),它等於 $ ms \pmod n $ . 大多數時候,這 $ ms $ value 將不會被正確填充(它不會以 0x00 0x02 開頭或不會包含額外的 0x00)。然而,以低但不可忽略的機率(大約每 30000 到 130000 次嘗試一次),幸運的是 $ ms \pmod n $ 值看起來填充。如果是這種情況,那麼伺服器的行為將通知攻擊者這一事實。然後攻擊者得知,對於這個值 $ s $ (攻擊者知道這一點,因為他選擇了它),那麼 $ ms \pmod n $ 在特定範圍內(使用大端約定以字節編碼時以 0x00 0x02 開頭的整數範圍)。

其餘的攻擊再次嘗試,使用精心挑選的隨機值 $ s $ . 每次伺服器響應“這是一個適當的 PKCS#1 填充”時,這都會提供一些資訊,幫助攻擊者縮小猜測範圍 $ m $ . 在總共數百萬個連接之後,攻擊者學到了足夠的知識來查明確切的 $ m $ ,產生預主密鑰。

詳情見原文;一旦你知道 RSA 填充是如何工作的,剩下的就是數學,這並不難。

為了防止這種攻擊,SSL 伺服器不會通知客戶端有關填充問題。如果由於填充錯誤導致解密失敗,則伺服器繼續使用隨機的預主密鑰(在處理Finished消息時將發生真正的失敗)。

可能會注意到 PKCS#1 v1.5 填充(用於加密)的特定弱點是它不是很多餘;隨機字節確實是隨機的,沒有任何特別強制的值。這就是允許以很小但不可忽略的機率“正確填充”隨機字節序列的原因。較新版本的PKCS#1描述了一種新的填充類型,稱為 OAEP,它使用散列函式添加大量內部冗餘,這使得隨機字元串與填充格式匹配的可能性極小。這可以防止 Bleichenbacher 的攻擊。不幸的是,SSL 仍然使用 PKCS#1 v1.5。

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