簡體   English   中英

Cipher.doFinal輸出大小

[英]Cipher.doFinal output size

我正在使用javax.crypto在java中進行AES CBC解密。 我使用以下Cipher類方法:

  • 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的一般行為,這是我的代碼到目前為止所表現出的行為,但這種假設是否會持續存在?

一般情況下 (如在Cipher類的上下文中),我認為假設這樣做是不安全的。 根據doFinal方法的javadoc

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

因此,如果您將輸出緩沖區“分配”在調用doFinal方法的位置“接近”,則調用getOutputSize並分配適當大小的緩沖區是有意義的。 任務完成。

另一方面,如果您從“遠處”傳入一個緩沖區,而該緩沖區的創建恰好是塊大小,那么您可能會遇到更多麻煩。 只要getOutputSize方法返回適當的大小,Cipher實現返回大於塊大小的輸出就完全合法(至少,根據Java類的公共接口)。

事實上,如果您正在進行CBC解密,那么是否要求您將所有塊傳遞給update方法? 在這種情況下,您應該從doFinal獲取完整的純文本輸出,而不僅僅是一個塊?

一般來說,假設緩沖僅適用於一個塊是不安全的; 當你查看細節時,你可能會發現它取決於填充的類型。 使用通常的“PKCS#5”填充,添加至少一個字節且最多n個字節(對於大小為n的塊),因此解密系統可以將其自身限制為n個字節的緩沖。 一些其他類型的填充有點復雜,例如CTS需要2n字節的緩沖。 Java加密層現在似乎不支持CTS,但可能會在將來的版本中添加。

給定len額外輸入字節, Cipher.getOutputSize(len)將為您提供最大輸出大小。 返回的值可能稍微大於實際返回的值,特別是在解密時,因為它取決於在解密時實際找到的填充字節。

可以安全地假設總解密消息長度不長於總加密消息長度(對稱加密不涉及數據壓縮)。 因此,您可以維護兩個計數器,一個用於輸入數據字節(加密塊),另一個用於獲取的輸出數據字節; 差異將是從doFinal()獲得的最大界限。 但這就是getOutputSize()無論如何都要做的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM