2011-07-12 215 views
0

我們使用Rijndael加密來加密所有類型的文件。較新的.xlsx和.docx文件在嘗試打開時(在加密並嘗試解密後)發生錯誤。 Excel 2003嘗試打開文件時出錯:「轉換器無法打開文件」。我有Excel加上安裝和不使用加密/解密時,我可以在Excel 2003中打開xlsx文件。使用C#AES或Rijndael加密和解密xlsx,docx文件

我已經更改了代碼使用AES,具有相同類型的問題(但在這種情況下文件將不會下載,只是在Firefox下載列表中)。我在這裏閱讀了一些建議,關注加密/解密文件的字節大小/長度,但在如何解決這個問題方面存在一些問題,我發現如果我上傳一個xls文件,加密文件的長度是不同的從解密的文件出來和xls保存並打開罰款,所以我不知道如何測試這是否是問題,因爲這些長度不同的文件可以工作。我將包含代碼,以查看是否有人可以發現任何可能導致xlsx/docx文件加密錯誤的問題。我已經最小化了代碼,所以如果有任何語法錯誤,可能是由於這個原因。

我已經安裝了Excel 2007,查看加密和解密的.xlsx文件是否將在Excel 2007中打開。當我嘗試打開該文件時,出現提示:「Excel在'myfile.xlsx中發現了無法讀取的內容'你想恢復這本工作手冊的內容嗎?「。 Excel 2007能夠使用以下消息恢復/修復該文件:「Excel完成了文件級別驗證和修復,此工作簿的某些部分可能已被修復或丟棄」。因此,加密/解密會創建無效文件,但Excel 2007能夠修復此問題; Excel 2003轉換器無法對文件執行任何操作。

public byte [] Encrypt(byte [] bytes) 
     { 
      if (myRijndael == null) 
       myRijndael = new RijndaelManaged(); 
      ICryptoTransform encryptor = myRijndael.CreateEncryptor(key, IV); 
      MemoryStream msEncrypt = new MemoryStream(); 
      CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write); 
      csEncrypt.Write(bytes, 0, bytes.Length); 
      csEncrypt.FlushFinalBlock(); 
      return msEncrypt.ToArray(); 
     } 

public byte [] Decrypt(byte [] encrypted, string text) 
     { 
      if (myRijndael == null) 
{ 
        myRijndael = new RijndaelManaged(); 
} 
      ICryptoTransform decryptor = myRijndael.CreateDecryptor(key, IV); 
      MemoryStream msDecrypt = new MemoryStream(encrypted); 
      CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read); 
      byte [] fromEncrypt = new byte[encrypted.Length]; 
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); 
      return fromEncrypt; 
} 


Usage: 
ENCRYPT: 
ClcCrypto crypt; // Our class for saving keys etc. 
ClcCrypto(CLC.WebUtil.ClcCrypto.GetDecryptionKey(), Group.IV); 
BinaryReader br = new BinaryReader(NewFile);// NewFile is Stream from filMyFile.PostedFile.InputStream 
byte[] EncryptedContents = crypt.Encrypt(br.ReadBytes((int)NewFile.Length)); 
FileStream fs = File.Create(DestFileName); 
BinaryWriter bw = new BinaryWriter(fs); 
bw.Write(EncryptedContents); 
bw.Close(); 
fs.Close(); 
br.Close(); 

DECRYPT (file download): 
byte[] baOut = null; 
baOut = fiOut.GetFileData(out lLength); // See below for method 
Response.AddHeader("content-disposition", "attachment; filename=" + FileName)); 
Response.ContentType = fiOut.MimeType; 
Response.AddHeader("content-length", lLength.ToString()); 
Response.BinaryWrite(baOut); 
Response.End(); 

public byte[] GetFileData(out long intFileSize) 
{ 
FileStream fsOut = new FileStream(FilePath, FileMode.Open, FileAccess.Read); 
     intFileSize = fsOut.Length; 
     byte[] Buffer = null; 
     ClcCrypto crypt; 
     crypt = new CLC.WebUtil.ClcCrypto(CLC.WebUtil.ClcCrypto.GetDecryptionKey(), IV); 
     BinaryReader br = new BinaryReader(fsOut); 
     Buffer = crypt.Decrypt(br.ReadBytes((int)fsOut.Length), null); 
     br.Close(); 
     fsOut.Close(); 
     return Buffer; 
} 

回答

0

聽起來像一個截斷的問題;可能是因爲你創建內存流的方式;當我解密它看起來像下面

MemoryStream msDecrypt = new MemoryStream(); 
CryptoStream csDecrypt = new CryptoStream(
    msDecrypt, 
    decryptor, 
    CryptoStreamMode.Write); 
csStream.Write(encrypted, 0, encrypted.Length); 
csStream.Flush(); 
return csDecrypt.ToArray(); 

我猜想,有多餘被追加,並使用另一種方法可以緩解這個空字節。