2014-10-07 56 views
3

在解密數據之前是否可以獲得解密數據的最終長度?以下是一個示例:CryptoStream的長度可以在解密之前確定嗎?

RijndaelManaged RMCrypto = new RijndaelManaged(); 
RMCrypto.Padding = PaddingMode.ISO10126; 
Response.Buffer = false; 
Response.ClearHeaders(); 
Response.ClearContent(); 
Response.AddHeader("Content-length", ??????); 
CryptoStream crypto = new CryptoStream(Response.OutputStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Write); 
using (Stream orig = GetDataStream()) 
{ 
    int bufferSize = 100000; 
    int bytesReceived = bufferSize; 
    byte[] buffer = new byte[bufferSize]; 
    while (bytesReceived == bufferSize) 
    { 
     bytesReceived = orig.Read(buffer, 0, bufferSize); 
     crypto.Write(buffer, 0, bytesReceived); 
    } 
    crypto.FlushFinalBlock(); 
} 
Response.End(); 

此代碼已被簡化。源數據被加密並從GetDataStream()方法中檢索爲Stream。如果未包含content-length標題,則瀏覽器將無法提供下載文件的完整百分比或時間估計。提前解密流是不成問題的,因爲流可能在千兆字節大小範圍內,並通過網絡讀取。

回答

1

如果你知道塊加密模式和填充模式被使用,那麼是的,這是可以提前確定的時間長度。 (例如,如果您使用的是CBC,那麼您可以使用倒數第二個密文塊作爲IV,最終密文塊作爲實際密文,然後計算出有多少個填充字節。)

大多數開發人員只是去「???」在上述情況下以更簡單的方式解決問題:在初始加密過程中將明文長度存儲在某處。

0

不,即使在收到CBC使用的最後一個加密塊之後,您也無法知道恰恰是。此外,CBC加密不會將密文的大小存儲在任何地方。 你知道,明文裏面是一樣的密文,減一 15個字節(塊大小 - 1)AES不過,不包括IV大小。您收到的最後塊可以使用第一到最後一個塊作爲IV,雖然解密最終塊(同利維的答案)檢查的精確長度明文之後。

內容首部是用於在體內的全部內容,所以這將是密文:

的Content-Length的實體頭字段指示實體主體, 的十進制數的大小的OCTETs,發送給接收方,或者在方法HEAD的情況下,發送的實體主體的大小具有請求 成爲GET。

所以??????在你的問題中應該是而不是是明文的大小,但是密文的大小(包括IV,認證標記和其他開銷,如果存在的話)。

如果你想知道以字節爲單位的確切明文大小事前,簡單地存儲在密文的前64位(大端)整數。它與密文大小非常相關,所以我不認爲它是非常保密的。

另一種巧妙的方法是使用CTR或GCM模式加密。 CTR的密文是 - 禁止IV大小 - 與明文大小完全相同。 GCM增加了一個認證標籤,但是否使用CTR來進行加密。請注意,對於這些模式中的任何一種,IV都不應重複使用相同的密鑰。

相關問題