2012-02-08 72 views
2

我試圖解密一些通過TCP套接字接收的數據。這是在CFB模式下使用RijndaelManaged類來完成的。我的問題是,我不知道我應該如何解密數據,因爲我只處理幾個字節(8到20取決於消息)。當我使用10字節byte[]呼叫TransformFinalBlock時,我收到一條異常消息:「要解密的數據的長度無效。」如果我撥打TransformBlock並獲得這10個字節:「價值無效。」所以這裏是我的問題:使用AES解密少量字節

  1. 我收到的消息的長度在前4個字節中的消息的其餘部分。我怎麼能解密這些字節來確定繼續閱讀的長度?
  2. 即使我暫時將要讀取的字節數編碼爲10(針對此特定消息)並從網絡讀取這些字節,如何解密這10個字節?

我也嘗試過使用CryptoStream來讓它直接從我的NetworkStream中讀取。但是,任何讀取調用似乎都會無限期地阻止。我有一種感覺,它期待更多的數據被髮送(可能是一個完整的塊大小的字節)。

我無法訪問在網絡上發送此數據的其他節點,因此我無法將協議更改爲在開始時包含未加密的字節,以指示長度或任何內容。此外,據推測,還有其他人與此成功溝通,因此它必須是可能的。

+0

我真的不知道答案,但這與密碼填充有關。實際上可以使用分組密碼對不完整的塊進行加密,而無需任何開銷。 – usr 2012-02-08 22:32:50

+0

爲什麼不等待剩餘的字節? – sprinter252 2012-02-08 22:32:57

+0

@usr yes我認爲某些類型的手動填充可以幫助我解決#2,但我仍然不知道如何處理#1。 – Dennis 2012-02-08 22:36:12

回答

0

當你處理TCP流時,如果你使用長度前綴,你通常必須以某種形式緩衝你的數據,當讀到這個階段時你有一個階段「Reading Length」,當你切換到「Reading data」時長度被滿足,你傳遞已經被讀取的字節並切換回「讀取長度」...

記住你可能沒有收到你在單次讀取中發送的所有內容,或者你可能收到多於一次的發送在1讀。

長度是否也加密?是否可能是以未加密的方式預先確定長度,然後對有效載荷進行加密? ......如果在解密數據之前不知道需要閱讀多少內容,那麼知道需要閱讀多少內容會更困難。

推薦: 4字節(還有其他方法),用於加密的有效載荷的長度

讀字節直到長度剛剛讀取已被接收。

(解密有效載荷)

4字節...

n字節...

(解密)

重複而流連接。


如果您對加密結束有控制權。

功能接收輸入字節 加密返回Encypted字節

發送加密的字節長度(4字節) 發送加密字節

重複爲每個輸入塊。

+0

你如何解密只是前4個字節(或所有的字節假設我可以找出多少全部)? – Dennis 2012-02-08 23:09:22

+0

在我的一個10字節消息的例子中,所有10個字節都被加密了。通常我想讀取前4個字節來確定剩餘的字節數,但前4個字節也被加密。理想情況下,我想解密這些字節,然後根據解密的值讀取剩餘的字節,然後解密剩餘的字節。但我似乎無法一次只解密4個字節(也不是6或10)。 – Dennis 2012-02-08 23:11:11

+0

你真的需要加密長度嗎? – 2012-02-08 23:14:19

1

當使用特定塊大小爲N的密碼系統時,輸出中的每一位都取決於輸入中至少有N位的狀態。在許多現代系統如AES的情況下,塊大小將是128或256位(即16或32字節)。雖然有一些方案可以在不需要填充的情況下對長度不是塊大小倍數的文件進行加密(例如,如果文件是256位的倍數,再加上一個額外的32位,則通常的方案是通過加密由最後的224個加密比特組成的塊和剩餘的32個未加密的比特),通常不可能加密比塊小的任何東西。

您將不得不加密文件的前16/32個字節,使用長度,然後將讀取的「額外」12或28個字節視爲第一個數據項的一部分,否則需要該數據項目的最小長度爲16或32個字節,並分別對它們進行加密,使長度不加密。

1

我能夠通過使用BouncyCastle庫而不是內置的.NET AES類來部分解決這個問題(我的#2問題)。

我第一次嘗試使用PKCS7手動填充加密的數據(我相信這是AES支持的唯一填充方案)。在手動填充的數據上使用RijndaelManaged類會導致「填充無效並且無法移除」異常。於是我試着使用BouncyCastle庫:

CfbBLockCipher cipher = new CfbBlockCipher(new AesEngine(), 128); 
cipher.Init(false, new ParametersWithIV(new KeyParameters(key), iv)); 
cipher.DecryptBlock(encrypted, 0, decrypted, 0); 

它的工作很完美。我不知道這是.NET中的一個錯誤還是什麼,但希望這可以幫助其他任何碰到這個問題的人。現在

,如果只有我能弄清楚如何解密這些前四個字節,所以我知道該消息將持續多久......(我的#1題)

編輯: 如果我使用BouncyCastle的的PaddedBufferBlockCipher我解密時出現「pad block corrupted」錯誤。這個數據有些奇怪,我只能在一個塊中手動解密,並且只能用BouncyCastle解密(.NET的TransformBlock只給出瞭解密值的零字節)。