2013-09-14 2 views
0

Я хочу расшифровать уже зашифрованный файл, но получаю сообщение об ошибке «Плохие данные». Я думаю, что метод, который я использовал для генерации ключа, не генерирует тот же ключ во время шифрования и дешифрования. Итак, я хочу объявить свой собственный ключ. Как я могу это сделать? Это мой код.Шифрование/дешифрование

using System; 
using System.IO; 
using System.Security; 
using System.Security.Cryptography; 
using System.Runtime.InteropServices; 
using System.Text; 
using System.Windows.Forms; 


public static class crypto 
{ 
    public static String tempdir = Environment.ExpandEnvironmentVariables("%temp%"); 


    // Call this function to remove the key from memory after use for security 
    [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint =   "RtlZeroMemory")] 
    public static extern bool ZeroMemory(IntPtr Destination, int Length); 

    // Function to Generate a 64 bits Key. 
    static string GenerateKey() 
    { 
     // Create an instance of Symetric Algorithm. Key and IV is generated automatically. 
     DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create(); 
     Clipboard.SetText(desCrypto.Key.ToString()); 
     // Use the Automatically generated key for Encryption. 
     return ASCIIEncoding.ASCII.GetString(desCrypto.Key); 
    } 

    static void EncryptFile(string sInputFilename, 
     string sOutputFilename, 
     string sKey) 
    { 
     FileStream fsInput = new FileStream(sInputFilename, 
      FileMode.Open, 
      FileAccess.Read); 

     FileStream fsEncrypted = new FileStream(sOutputFilename, 
      FileMode.Create, 
      FileAccess.Write); 
     DESCryptoServiceProvider DES = new DESCryptoServiceProvider(); 
     DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey); 
     DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey); 
     ICryptoTransform desencrypt = DES.CreateEncryptor(); 
     CryptoStream cryptostream = new CryptoStream(fsEncrypted, 
      desencrypt, 
      CryptoStreamMode.Write); 

     byte[] bytearrayinput = new byte[fsInput.Length]; 
     fsInput.Read(bytearrayinput, 0, bytearrayinput.Length); 
     cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length); 
     cryptostream.Close(); 
     fsInput.Close(); 
     fsEncrypted.Close(); 
    } 

    static void DecryptFile(string sInputFilename, 
     string sOutputFilename, 
     string sKey) 
    { 
     DESCryptoServiceProvider DES = new DESCryptoServiceProvider(); 
     //A 64 bit key and IV is required for this provider. 
     //Set secret key For DES algorithm. 
     DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey); 
     //Set initialization vector. 
     DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey); 

     //Create a file stream to read the encrypted file back. 
     FileStream fsread = new FileStream(sInputFilename, 
      FileMode.Open, 
      FileAccess.Read); 
     //Create a DES decryptor from the DES instance. 
     ICryptoTransform desdecrypt = DES.CreateDecryptor(); 
     //Create crypto stream set to read and do a 
     //DES decryption transform on incoming bytes. 
     CryptoStream cryptostreamDecr = new CryptoStream(fsread, 
      desdecrypt, 
      CryptoStreamMode.Read); 
     //Print the contents of the decrypted file. 
     StreamWriter fsDecrypted = new StreamWriter(sOutputFilename); 
     fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd()); 
     fsDecrypted.Flush(); 
     fsDecrypted.Close(); 
    } 


    public static void Encrypt(String table, String file) 
    { 
     GenerateKey(); 
     try 
     { 
      String filepath = Path.Combine(tempdir + @"\Manager\data\" + table,file); 


      // Must be 64 bits, 8 bytes. 
      // Distribute this key to the user who will decrypt this file. 
      string sSecretKey; 

      // Get the Key for the file to Encrypt. 
      sSecretKey = GenerateKey(); 

      // For additional security Pin the key. 
      GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned); 

      // Encrypt the file.   
      EncryptFile(@"" + filepath, 
       @"" + Application.StartupPath + @"\data\"+ table + @"\" + file, 
       sSecretKey); 
      try 
      { 
       File.Delete(filepath); 
      } 
      catch (Exception ex1) 
      { 
       MessageBox.Show(ex1.Message, "Error while deletion of decrypted file"); 
      } 
      // Remove the Key from memory. 
      ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2); 
      gch.Free(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error during encryption"); 
     } 

    } 
    public static void Decrypt(String table, String file) 
    { 
     try 
     { 
      String filepath = Path.Combine(tempdir + @"\Manager\data\"+table, file); 
      create.folder("Manager", tempdir); 
      create.folder(table, tempdir + @"\Manager\"); 
      create.file(file, tempdir + @"\Manager\" + table); 

      // Must be 64 bits, 8 bytes. 
      // Distribute this key to the user who will decrypt this file. 
      string sSecretKey; 

      // Get the Key for the file to Encrypt. 
      sSecretKey = GenerateKey(); 

      // For additional security Pin the key. 
      GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned); 


      // Decrypt the file. 
      DecryptFile(@".\data\" + table + @"\" + file, 
       @"" + filepath, 
       sSecretKey); 



      // Remove the Key from memory. 
      ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2); 
      gch.Free(); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error during decryption"); 
     } 
    } 
} 
+1

Ужасно небезопасно. 1) DES 2) вы используете ключ как IV. Вы должны создать новый IV для каждого шифрования. 3) Недостаток MAC открывает вам активные атаки, наиболее заметные прописные оракулы. 4) Не используйте ASCII для преобразования ключей из/в текст. Используйте hex или Base64. – CodesInChaos

ответ

0

Ваш GenerateKey метод генерирует новый (случайный) ключ каждый раз, когда вы называете это (как вы уже говорили в комментариях есть). Если вы хотите использовать случайный ключ, сохраните сгенерированный ключ где-нибудь и используйте его для дешифрования и шифрования. Вы можете использовать собственный «пароль» для шифрования, предоставив вашему методу шифрования/дешифрования собственное строковое значение. например

crypto.EncryptFile(@"D:\Testing\brownfox.txt", @"D:\Testing\brownfox_enc.txt", "abcd1234"); 
crypto.DecryptFile(@"D:\Testing\brownfox_enc.txt", @"D:\Testing\brownfox_dec.txt", "abcd1234"); 

Как вы можете видеть в ссылке MSDN к «DES.Key», DES поддерживает ключи длиной 64 бит, поэтому важно отметить, что строка должна быть 8 символов.