2017-02-28 64 views
0

工作時,我試圖加密和解密簡單的字符串,一切都完美的罰款..C#的Rijndael解密不JPG格式

但是,當我編碼的JPG格式轉換爲bytearray,並與做同樣的事情bytearray,解密不再工作(bytearray是完全不同的原來的,不能再顯示)...

是因爲bytearray太大?

還是有人有我的問題的解決方案?

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Security.Cryptography; 
using System.Text; 
using System.Threading.Tasks; 

namespace Encrypter2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 

       Console.WriteLine(); 
       // Create a new instance of the Rijndael 
       // class. This generates a new key and initialization 
       // vector (IV). 
       byte[] originalFile = File.ReadAllBytes(@"C:/Users/Elron/Documents/Visual Studio 2015/Projects/FileEncrypt/FileEncrypt/bin/Debug/harambe.jpg"); 
       using (Rijndael myRijndael = Rijndael.Create()) 
       { 
       //  Encrypt the string to an array of bytes 
       // Encrypted byte[] 
       byte[] encrypted = EncryptStringToBytes(originalFile, myRijndael.Key, myRijndael.IV); 
        using (FileStream fs = File.Create(@"C:/Users/Elron/Documents/Visual Studio 2015/Projects/FileEncrypt/FileEncrypt/bin/Debug/harambeEncrypted.jpg")) 
        { 
         //Add some information to the file. 
         fs.Write(encrypted, 0, encrypted.Length); 
        } 
       //  Decrypted byte[] 
       byte[] roundtrip = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV); 
        using (FileStream fs = File.Create(@"C:/Users/Elron/Documents/Visual Studio 2015/Projects/FileEncrypt/FileEncrypt/bin/Debug/harambeDecrypted.jpg")) 
        { 
         //Add some information to the file. 
         fs.Write(roundtrip, 0, roundtrip.Length); 
        } 
       // Display the original data and the decrypted data. 
       // Encrypted string 
        Console.ReadKey(); 
      } 

      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Error: {0}", e.Message); 
      } 
     } 

     static byte[] EncryptStringToBytes(byte[] plainText, byte[] Key, byte[] IV) 
     { 
      // Check arguments. 
      if (plainText == null || plainText.Length <= 0) 
       throw new ArgumentNullException("plainText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("IV"); 
      byte[] encrypted; 
      // Create an Rijndael object 
      // with the specified key and IV. 
      using (Rijndael rijAlg = Rijndael.Create()) 
      { 
       rijAlg.Key = Key; 
       rijAlg.IV = IV; 

       // Create an encryptor to perform the stream transform. 
       ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV); 

       // Create the streams used for encryption. 
       using (MemoryStream msEncrypt = new MemoryStream()) 
       { 
        using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
        { 
         using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
         { 

          //Write all data to the stream. 
          string toEncrypt = Encoding.Default.GetString(plainText); 
          swEncrypt.Write(toEncrypt); 
         } 
         encrypted = msEncrypt.ToArray(); 
        } 
       } 
      } 


      // Return the encrypted bytes from the memory stream. 
      return encrypted; 

     } 

     static byte[] DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV) 
     { 
      // Check arguments. 
      if (cipherText == null || cipherText.Length <= 0) 
       throw new ArgumentNullException("cipherText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("IV"); 

      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 
      byte[] returnText; 

      // Create an Rijndael object 
      // with the specified key and IV. 
      using (Rijndael rijAlg = Rijndael.Create()) 
      { 
       rijAlg.Key = Key; 
       rijAlg.IV = IV; 

       // Create a decryptor to perform the stream transform. 
       ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); 

       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 
        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) 
        { 
         using (StreamReader srDecrypt = new StreamReader(csDecrypt)) 
         { 
          // Read the decrypted bytes from the decrypting stream 
          // and place them in a string. 
          plaintext = srDecrypt.ReadToEnd(); 


          ASCIIEncoding asc = new ASCIIEncoding(); 
          returnText = asc.GetBytes(plaintext); 
         } 
        } 
       } 
      } 
      return returnText; 
     } 
    } 
} 
+2

在二進制數據上使用StreamReader和StreamWriter(用於文本)是沒有意義的。你從哪裏複製粘貼這段代碼,並且你知道它在做什麼?你首先想要解決什麼問題? – CodeCaster

+1

我從MSDN頁面複製了它,然後觀看了很多Stream教程,並試圖理解它,是的 – Mreifenberger

回答

0

我認爲你是在你的加密和解密方法

static byte[] DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV) 
{ 
    ... 
    ASCIIEncoding asc = new ASCIIEncoding(); 
    returnText = asc.GetBytes(plaintext); 
    ... 
} 

而且

static byte[] EncryptStringToBytes(byte[] plainText, byte[] Key, byte[] IV) 
    { 
     ... 
     string toEncrypt = Encoding.Default.GetString(plainText); 
     swEncrypt.Write(toEncrypt); 
     ... 
    } 
+0

作爲一個方面說明,我沒有發現'File - > byte [] - > string - > Encrypt - > string - > byte []'保持簡單,以避免錯誤 – bradbury9

+0

非常感謝,我會看看!整個轉換的東西是因爲當我不這樣做,我剛剛返回System.Byte [];這是沒有用的時候......當我試圖直接做它沒有所有的轉換東西我得到了一堆的錯誤,因爲寫操作需要一個字符串,不能正確轉換或類似的東西 – Mreifenberger

+0

注意:編碼是問題!非常感謝! – Mreifenberger

3

你不能把字節字符串的任意陣列使用不同的編碼。您將字節數轉換爲字符串,然後將該字符串寫入StreamWriter,該字符串將字符串轉換回字節。這將是一堆任意字節的有損操作。

您的方法EncryptStringToBytes是一個錯誤的概念。你應該有一個方法EncryptBytes(和DecryptBytes),它們不關心字符串。然後你可以傳入一個字節數組並將其直接送入CryptoStream。如何解釋這些字節並不是加密算法的關注點。

所以,你可以調整你的方法如下:

static byte[] EncryptBytes(byte[] bytes, byte[] Key, byte[] IV) 
{ 
    // Check arguments. 
    if (bytes == null || bytes.Length <= 0) 
     throw new ArgumentNullException("bytes"); 
    if (Key == null || Key.Length <= 0) 
     throw new ArgumentNullException("Key"); 
    if (IV == null || IV.Length <= 0) 
     throw new ArgumentNullException("IV"); 
    // Create an Rijndael object 
    // with the specified key and IV. 
    using (Rijndael rijAlg = Rijndael.Create()) 
    { 
     rijAlg.Key = Key; 
     rijAlg.IV = IV; 

     // Create an encryptor to perform the stream transform. 
     ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV); 

     // Create the streams used for encryption. 
     using (MemoryStream msEncrypt = new MemoryStream()) 
     { 
      using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, 
        CryptoStreamMode.Write)) 
      { 
       csEncrypt.Write(bytes,0,bytes.Length); 
       csEncrypt.FlushFinalBlock(); 
       return msEncrypt.ToArray(); 
      } 
     } 
    } 
} 

static byte[] DecryptBytes(byte[] encryptedBytes, byte[] Key, byte[] IV) 
{ 
    // Check arguments. 
    if (encryptedBytes == null || encryptedBytes.Length <= 0) 
     throw new ArgumentNullException("encryptedBytes"); 
    if (Key == null || Key.Length <= 0) 
     throw new ArgumentNullException("Key"); 
    if (IV == null || IV.Length <= 0) 
     throw new ArgumentNullException("IV"); 

    // Create an Rijndael object 
    // with the specified key and IV. 
    using (Rijndael rijAlg = Rijndael.Create()) 
    { 
     rijAlg.Key = Key; 
     rijAlg.IV = IV; 

     // Create a decryptor to perform the stream transform. 
     ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); 

     // Create the streams used for decryption. 
     using (MemoryStream msDecrypt = new MemoryStream()) 
     { 
      using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, 
        CryptoStreamMode.Write)) 
      { 
       csDecrypt.Write(encryptedBytes,0,encryptedBytes.Length); 
       csDecrypt.FlushFinalBlock(); 
       return msDecrypt.ToArray(); 
      } 
     } 
    } 

} 

然後用往返測試:

using(var rijndael = Rijndael.Create()) 
{ 
    var stringToEncrypt = "foobar"; 
    var bytesToEncrypt = Encoding.UTF8.GetBytes(stringToEncrypt); 
    var encryptedBytes = EncryptBytes(bytesToEncrypt, rijndael.Key, rijndael.IV); 
    var decryptedBytes = DecryptBytes(encryptedBytes, rijndael.Key, rijndael.IV); 
    var originalString = Encoding.UTF8.GetString(decryptedBytes); 
    Debug.Assert(string.Equals(stringToEncrypt, originalString, 
           StringComparison.InvariantCulture)); 
} 

希望,通過這一點,很明顯如何我們已經從加密中解決了字符串編碼問題,以及您現在如何重新利用這些方法ods適用於任何類型的二進制數據。

+0

嗯,我想我對此太沒經驗了....這只是MSDN代碼,我試圖讓它適合我的應用程序。 – Mreifenberger

+0

@Mreifenberger請參閱我的編輯。 – spender

+0

@Mreifenberger上面的代碼有問題......現在就開始工作。 – spender