2010-08-13 67 views
3

我正在使用javax.crypto在java中進行AES CBC解密。我使用下面的密碼類方法:Cipher.do最終輸出大小

  • public final void init (int opmode, Key key, AlgorithmParameters params)用於初始化方法,
  • 解密數據
  • final int update(byte[] input, int inputOffset, int inputLen, byte[] output)方法,
  • 最後我稱之爲final int doFinal(byte[] output, int outputOffset)方法來完成解密。

我的查詢是這樣的嗎?我可以假設doFinal調用返回給我的數據大小總是小於或等於AES塊大小?該文檔將doFinal方法描述爲:

「完成多部分轉換 (加密或解密)。處理 在先前的更新調用中可能已經緩衝了 的任何字節。最後 轉化字節存儲在 輸出緩衝區。」

但無處說,輸出緩衝區包含的數據最多一個塊。雖然我明白這是AES API的一般行爲,而這是我的代碼迄今爲止所展示的行爲,但是這種假設一直會持續嗎?

+0

爲了清楚起見,我需要多次調用更新函數,因爲我以塊的形式獲取加密數據。我沒有整個加密的數據,所以我不能做一個單一的調用doFinal來一步獲得輸出。 – vikas 2010-08-13 10:06:26

回答

3

一般(如在Cipher類的情況下)我不認爲這是可以安全的假設這一點。由於每javadocsdoFinal方法:

如果輸出緩衝區太小無法保存該結果,則拋出ShortBufferException。在這種情況下,使用更大的輸出緩衝區重複此調用。使用getOutputSize來確定輸出緩衝區應該有多大。

所以,如果你分配輸出緩衝器「近」在這裏你調用doFinal方法的點,那麼它會是有意義的調用getOutputSize並分配適當大小的緩衝區。任務完成。另一方面,如果您傳入的「遠處」緩衝區已創建爲塊大小,則可能會遇到更多麻煩。根據Java類的公共接口,只要getOutputSize方法返回適當的大小,Cipher實現返回大於塊大小的輸出將是完全合法的(至少,根據Java類的公共接口)。

事實上,如果你在做CBC解密,是不是要求你把所有的塊都傳給update方法?在這種情況下,您應該從doFinal得到完整的純文本輸出,而不僅僅是一個塊?

+0

對'update'和'doFinal'使用'getOutputSize(固定輸入大小)'的字節數組是安全嗎? – 2012-04-09 13:16:07

+0

@Jin我不知道這是否會產生真正意義,因爲它們是兩回事。提供給'update'的字節數組應該是您要更新密碼的數據的大小 - 它需要與* input *中的字節數相同。如果這肯定小於或等於'getOutputSize()',那麼你*可以*重用相同的數組。實際上,儘管我懷疑這會比有幫助的更困惑。 – 2012-04-10 07:58:44

0

一般而言,假設緩衝區僅用於一個塊是不安全的;並且當您查看細節時,可能會看到它取決於填充類型。使用通常的「PKCS#5」填充,添加至少一個字節和至多一個字節(對於大小爲的塊()),因此解密系統可以將其自身限制爲字節的緩衝。一些其他類型的填充有點複雜,例如CTS要求2n字節的緩衝。 Java密碼層現在似乎不支持CTS,但可能會在未來版本中添加。

Cipher.getOutputSize(len)會給你最大的輸出大小,給出len額外的輸入字節。返回的值可能比實際返回的值大一些,特別是對於解密,因爲它取決於在解密時實際會發現哪些填充字節。

可以安全地假設總解密消息長度不超過總加密消息長度(對稱加密不涉及數據壓縮)。所以你可以維護兩個計數器,一個用於輸入數據字節(加密塊),另一個用於獲得的輸出數據字節;差異將是從doFinal()可以獲得的最大範圍。但這就是getOutputSize()無論如何。

+0

在我的情況下使用的填充只是'PKCS5Padding'。這是否意味着我可以假定最大輸出尺寸是AES塊尺寸? 我不能使用'Cipher.getOutputSize(len)'的原因是因爲存儲'doFinal()'輸出的緩衝區被分配並傳遞給遠離我不應該修改的代碼的模塊。並且分配的緩衝區的大小是AES塊大小。 – vikas 2010-08-13 12:58:25

+0

你不能假設,但你可以檢查它。如果塊的大小爲_n_,並且加密的消息由_k_塊組成,則總解密的消息長度在_n(k-1)_和_(nk)-1_(含)之間。使用計數器,您可以知道(在運行時)剩餘的緩衝數據在解密時是否適合尺寸爲_n_的緩衝區。你不能假設_in advance_因爲這不是Java密碼體系結構的保證屬性。 – 2010-08-13 13:35:22