Шифрование и дешифрование файлов xlsx, docx с помощью C# AES или Rijndael

Мы шифруем все типы файлов с помощью шифрования Rijndael. Более новые файлы .xlsx и .docx выдают ошибки при попытке открытия (после шифрования и попытки расшифровки). Ошибка при попытке Excel 2003 открыть файл: «Преобразователю не удалось открыть файл». У меня установлено дополнение Excel, и когда шифрование/дешифрование не используется, я могу открывать файлы xlsx в Excel 2003.

Я изменил код для использования 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;
}

person user638303    schedule 12.07.2011    source источник


Ответы (2)


Если набивка вызывает беспокойство, вот кое-что для вас:

Как мне зашифровать строку в vb.net с помощью RijndaelManaged и заполнения PKCS5?

person Daniel Mošmondor    schedule 12.07.2011

Звучит как проблема усечения; возможно, из-за того, как вы создаете поток памяти; когда я расшифровываю это выглядит следующим образом

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

Я предполагаю, что добавляются дополнительные нулевые байты, и использование альтернативного подхода может облегчить это.

person blowdart    schedule 13.07.2011