2012-05-05 4 views
1

У меня есть небольшое приложение, которое среди прочего читает любой файл (например, .exe, .png,. Img и все остальные), переносит его на bytes[] прогиб File.ReadAllBytes(), шифрует его с помощью 3DES и сохраняет с File.WriteAllBytes(). Тогда есть метод дешифрования, который делает то же самое обратное. Моя проблема в том, что все работает нормально до 300 МБ оригинального файла, чем у меня есть исключение из памяти. Любое предложение, как решить эту проблему? Как работать с файлами> 1 ГБ? Может ли это помочь использовать читатель или читатель криптопотока?File.ReadAllBytes() Исключено из памяти

Чтение и шифрования файлов:

try 
{ 
    saveFileDialog1.FileName = ""; 
    DialogResult result = openFileDialog1.ShowDialog(); 
    if (result == DialogResult.OK) 
    { 
     byte[] Results; 
     System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
     fileToEncrypt = File.ReadAllBytes(openFileDialog1.FileName); 
     MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
     byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(textBox1.Text)); 
     TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
     TDESAlgorithm.Key = TDESKey; 
     TDESAlgorithm.Mode = CipherMode.ECB; 
     TDESAlgorithm.Padding = PaddingMode.PKCS7; 
     ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor(); 
     Results = Encryptor.TransformFinalBlock(fileToEncrypt, 0, fileToEncrypt.Length); 
     saveFileDialog1.FileName = openFileDialog1.SafeFileName; 
     saveFileDialog1.ShowDialog(); 
     if (saveFileDialog1.FileName != "") 
     { 
      File.WriteAllBytes(saveFileDialog1.FileName, Results); 
     } 
     TDESAlgorithm.Clear(); 
     HashProvider.Clear(); 
    } 
} 
catch 
{ 
    MessageBox.Show("Your system has not enough memory.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); 
} 

дешифрование и экономия:

try 
{ 
    openFileDialog1.FileName = ""; 
    DialogResult result = openFileDialog1.ShowDialog(); 
    if (result == DialogResult.OK) // Test result. 
    { 
     byte[] Results; 
     System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
     fileToDecrypt = File.ReadAllBytes(openFileDialog1.FileName); 
     MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
     byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(textBox1.Text)); 
     TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
     TDESAlgorithm.Key = TDESKey; 
     TDESAlgorithm.Mode = CipherMode.ECB; 
     TDESAlgorithm.Padding = PaddingMode.PKCS7; 
     ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor(); 
     Results = Decryptor.TransformFinalBlock(fileToDecrypt, 0, fileToDecrypt.Length); 
     saveFileDialog1.FileName = Path.GetFileName(openFileDialog1.FileName); 
     saveFileDialog1.ShowDialog(); 
     if (saveFileDialog1.FileName != "") 
     { 
      File.WriteAllBytes(saveFileDialog1.FileName, Results); 
     } 
     TDESAlgorithm.Clear(); 
     HashProvider.Clear(); 
    } 
} 
catch 
{ 
    MessageBox.Show("Master password is wrong", "", MessageBoxButtons.OK, MessageBoxIcon.Error); 
} 

Я только хобби кодировщик, поэтому я молюсь за какой-то благосклонности с моим кодом :)

textbox1.Text является основной пароль.

+15

Не читайте файл в памяти, просто передайте 'FileStream' на метод шифрования – Magnus

+1

Умственная ошибка здесь заключается в том, что вы предполагаете, что поставщик криптографии также является потоком. Это не так, это просто алгоритм, который преобразует байты. Вы не использовали класс CrytoStream. Просто следуйте примеру MSDN: http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider.aspx –

+0

Похоже, вы ловите ВСЕ исключение. Как вы могли быть уверены, что это исключение OutOfMemoryException? –

ответ

0

Наконец-то у меня есть что-то, использующее криптопоток - на моем ноутбуке 8 минут для шифрования 2,7 ГБ файла. Благодаря Магнуса для усилий, я попробую ваш код также

метод шифрования

DialogResult result = openFileDialog1.ShowDialog(); 
     if (result == DialogResult.OK) 
     { 
      saveFileDialog1.FileName = openFileDialog1.SafeFileName; 
      saveFileDialog1.ShowDialog(); 
      FileStream readFile = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read); 
      FileStream writeFile = new FileStream(saveFileDialog1.FileName, FileMode.OpenOrCreate, FileAccess.Write); 
      writeFile.SetLength(0); 

      byte[] storage = new byte[100]; 
      long fileWritten = 0; 
      long totlen = readFile.Length; 
      int bytesToWrite; 

      System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
      MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
      byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(textBox1.Text)); 
      TripleDESCryptoServiceProvider TDES = new TripleDESCryptoServiceProvider(); 
      TDES.Key = TDESKey; 
      TDES.Mode = CipherMode.ECB; 
      TDES.Padding = PaddingMode.PKCS7; 
      CryptoStream cryptStream = new CryptoStream(writeFile, TDES.CreateEncryptor(), CryptoStreamMode.Write); 
      while (fileWritten < totlen) 
      { 
       bytesToWrite = readFile.Read(storage, 0, 100); 
       cryptStream.Write(storage, 0, bytesToWrite); 
       fileWritten = fileWritten + bytesToWrite; 

      } 

      cryptStream.Close(); 
      TDES.Clear(); 
      HashProvider.Clear(); 
     } 

метод дешифрования такой же, используя TDES.CreateDecryptor() вместо TDES.CreateEncryptor(). Должен сказать, что File.ReadAllBytes() и File.WriteAllBytes() намного быстрее с размером файла 300 МБ, чем поток.

+0

Буфер размером 100 - это малый размер, чтобы увеличить производительность. Не менее 4096. – Magnus

Смежные вопросы