2012-10-21 66 views
4

我相當新手加密,我試圖讓逐行加密工作;在應用程序運行期間,我需要能夠將加密行附加到文件中,而不僅僅是一個大型的大規模加密 - 一切 - 保存。儘管如此,我還是有一段野獸。這是我的加密,在我自己的幾次失敗的嘗試後,無恥被盜:逐行加密/解密文件?


class Encryption 
    { 
     private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22, 0x3c }; 

     public static byte[] Encrypt(byte[] plain, string password) 
     { 
      MemoryStream memoryStream; 
      CryptoStream cryptoStream; 
      Rijndael rijndael = Rijndael.Create(); 
      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT); 
      rijndael.Key = pdb.GetBytes(32); 
      rijndael.IV = pdb.GetBytes(16); 
      memoryStream = new MemoryStream(); 
      cryptoStream = new CryptoStream(memoryStream, rijndael.CreateEncryptor(), CryptoStreamMode.Write); 
      cryptoStream.Write(plain, 0, plain.Length); 
      cryptoStream.FlushFinalBlock(); 
      cryptoStream.Close(); 
      return memoryStream.ToArray(); 
     } 

     public static byte[] Decrypt(byte[] cipher, string password) 
     { 
      MemoryStream memoryStream; 
      CryptoStream cryptoStream; 
      Rijndael rijndael = Rijndael.Create(); 
      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, SALT); 
      rijndael.Key = pdb.GetBytes(32); 
      rijndael.IV = pdb.GetBytes(16); 
      memoryStream = new MemoryStream(); 
      cryptoStream = new CryptoStream(memoryStream, rijndael.CreateDecryptor(), CryptoStreamMode.Write); 
      cryptoStream.Write(cipher, 0, cipher.Length); 
      cryptoStream.FlushFinalBlock(); 
      cryptoStream.Close(); 
      return memoryStream.ToArray(); 
     } 
    } 

,這裏是一個虛擬函數展示如何我嘗試它:

 

     private void EncryptFile(string filepath, string outputPath, string password) 
     { 
      FileInfo fileInfo = new FileInfo(filepath); 
      string filename = fileInfo.Name; 

      string fullpath = outputPath + "\\" + filename; 

      BinaryWriter writer = new BinaryWriter(File.OpenWrite(fullpath), Encoding.ASCII); 

      /// Two methods that I've attempted here: 
      /// 1. The desired method: encrypt line by line - I assumed I'd be able to generate 
      ///  multiple blocks of data and decrypt them later. This isn't working 

      //string[] lines = File.ReadAllLines(filepath); 

      /// 2. Just read the whole thing and encrypt and write it in one swoop. 

      string line = File.ReadAllText(filepath); 

      //foreach(string line in lines) 
      { 
       byte[] bytes = Encoding.ASCII.GetBytes(line); 
       byte[] encoded = Encryption.Encrypt(bytes, password); 

       writer.Write(encoded); 
       writer.Flush(); 
      } 

      writer.Close(); 
     } 



     private void DecryptFile(string filepath, string outputPath, string password) 
     { 
      FileInfo fileInfo = new FileInfo(filepath); 
      string filename = fileInfo.Name; 
      string fullpath = outputPath + "\\" + filename; 

      StreamWriter writer = new StreamWriter(fullpath, false, Encoding.UTF8); 

      byte[] bytes = File.ReadAllBytes(filepath); 

      /// Here is the method that's working at the moment for decrypting; just 
      /// grab all the data and decrypt it on one swoop. 

      byte[] decrypted = Encryption.Decrypt(bytes, password); 

      string s = Encoding.ASCII.GetString(decrypted); 

      writer.Write(s); 
      writer.Flush(); 


      /// I've tried a number of things here to decrypt line by line, 
      /// none of which work. This crashes with an issue about the padding 
      /// being invalid. 

      /* 
      int index = 0; 
      int count = 32; 

      while (index

我不完全知道我應該再來一次。我一直徘徊在揣測事物和在線閱讀示例,但他們似乎都是如何加密整個文件,或者只是加密一段數據,除了立即解密它之外別無它物。我應該如何處理逐行寫作?

+1

輸出文件應該是什麼樣子?文本文件還是二進制流? – Serge

+2

你可能不想逐行閱讀。相反,你想抓住該文件作爲流http://www.csharp-examples.net/filestream-read-file/,然後使用cryptostream http://msdn.microsoft.com/en-us/library/system .security.cryptography.cryptostream.read.aspx。 – AlexGad

回答

4

不是爲你編程,而是給你一個你可以實現的方案。

如果你有每行加密,我想你也希望能夠解密每行。請注意,「行」對於計算機來說是一個相當不方便的術語。這只是一堆以某種行結束符結尾的字符。字符本身使用特定的進行編碼。

此外,我會做出以下假設:

  • 加密文本應線被呈現,這意味着該字節需要從二進制轉換爲字符(使用);
  • 您希望使用單個密鑰,同時保持安全;
  • 您不需要完整性保護或密文驗證,只需保密。

現在的想法很簡單:

  1. 創建使用基於密碼的密鑰導出函數一個鍵;
  2. 打開文本文件進行閱讀(使用正確的);
  3. 讀取一行並將該行再次轉換爲字節(例如,使用UTF-8);
  4. 創建一個輸出流,在下面創建一個字節數組;
  5. 創建一個隨機IV並將其寫入字節數組(IV總是單個塊大小);
  6. 創建加密流並將其連接到相同的輸出流;
  7. 加密編碼後的行;
  8. base 64對加密字節進行編碼,並確保它保留在一行中;
  9. 將編碼的加密行寫入新的文本文件。

爲了做相反的事,雖然應該從base 64解碼後的字節中檢索IV,並且當然應該使用與在加密期間使用的相同方法來計算密鑰。

+2

對於那些對加密沒有任何瞭解的人,IV是Initialization Vector。有時被稱爲「隨機數」或數字使用一次。 http://en.wikipedia.org/wiki/Initialization_vector – sholsinger