2014-03-14 12 views
3

我已經創建了一個簡單的加密和解密程序。我在這個程序中使用AESManaged類。密鑰和IV由使用Rfc2898DeriveBytes的預定義密碼派生而來。爲什麼我能夠使用AES 256Bit解密來解密已修改的加密數據

我測試我的程序如下所解釋:

  1. 輸入樣本文本到我的程序和捕獲的加密文本。
  2. 將相同的加密文本輸入到程序中,驗證的解密文本與我的原始文本相同。
  3. 在步驟2的加密文本中(「下一個字母」)修改「=」之前的字母並使用相同的密鑰廣告IV進行解密。我收到了原始文本。

在步驟#3我期待從程序中的錯誤,但它解密了錯誤的文本。

有人可以幫助我瞭解我的程序出了什麼問題,以及如何阻止我的程序解密錯誤的數據。

這裏是我的程序輸出:

Please put in input message 
Some Text 
Encrypted text is "xJzgOiMzimNOY6UsB+TNw9gUmcpdiZxQq70FxwbmkCc=" 
Please put in encrypted text to decrypt 
xJzgOiMzimNOY6UsB+TNw9gUmcpdiZxQq70FxwbmkCc= 
Decrypted text is "Some Text" 
Please put in encrypted text to decrypt <<here I have modified "c=" to "d=">> 
xJzgOiMzimNOY6UsB+TNw9gUmcpdiZxQq70FxwbmkCd= 
Decrypted text is "Some Text" 
Enter "Exit" to exit! 

AesExample.cs:

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Text; 

namespace Aes_Example 
{ 
    class AesExample 
    { 
     public static void Main() 
     { 
      string action, plainText, encryptedText, decryptedText; 

      Begin: 
      Console.WriteLine("Please put in input message"); 
      plainText = Console.ReadLine(); 

      encryptedText = Encrypt(plainText); 
      Console.WriteLine("Encrypted text is \"{0}\"", encryptedText); 

      Console.WriteLine("Please put in encrypted text to decrypt"); 
      encryptedText = Console.ReadLine(); 

      decryptedText = Decrypt(encryptedText); 
      Console.WriteLine("Decrypted text is \"{0}\"", decryptedText); 

      Console.WriteLine("Please put in encrypted text to decrypt"); 
      encryptedText = Console.ReadLine(); 

      decryptedText = Decrypt(encryptedText); 
      Console.WriteLine("Decrypted text is \"{0}\"", decryptedText); 

      Console.WriteLine("Enter \"Exit\" to exit!"); 
      action = Console.ReadLine(); 

      if (action.ToUpper() != "EXIT") { goto Begin; } 

     } 
     public static string Encrypt(string clearText) 
     { 
      string EncryptionKey = "[email protected]#52"; 
      byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); 

      using (AesManaged encryptor = new AesManaged()) 
      { 
       Rfc2898DeriveBytes pdb = new 
        Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
       encryptor.Key = pdb.GetBytes(32); 
       encryptor.IV = pdb.GetBytes(16); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(clearBytes, 0, clearBytes.Length); 
         cs.Close(); 
        } 
        clearText = Convert.ToBase64String(ms.ToArray()); 
       } 
      } 
      return clearText; 
     } 
     public static string Decrypt(string cipherText) 
     { 
      string EncryptionKey = "[email protected]#52"; 
      byte[] cipherBytes = Convert.FromBase64String(cipherText); 

      using (AesManaged encryptor = new AesManaged()) 
      { 
       Rfc2898DeriveBytes pdb = new 
        Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
       encryptor.Key = pdb.GetBytes(32); 
       encryptor.IV = pdb.GetBytes(16); 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(cipherBytes, 0, cipherBytes.Length); 
         cs.Close(); 
        } 
        cipherText = Encoding.Unicode.GetString(ms.ToArray()); 
       } 
      } 
      return cipherText; 
     } 

    } 
} 
+0

歡迎來到StackOverflow! +1爲非常好的問題:) – BradleyDotNET

回答

1

那你的字符串的最後="部分填充。

甚至沒有加密填充,但Base64填充。

短的版本:

byte[] data = { 1, 2, 3, 4 }; 
clearText = Convert.ToBase64String(data); 
cipherText = clearText.Replace("A==", "B=="); // crude test 
byte[] cipherBytes = Convert.FromBase64String(cipherText); 

在此之後,cipherBytes仍將{ 1, 2, 3, 4 }

Base64編碼使用6比特/字符,所以當有N個字節,它需要(N * 8)/ 6個字符。通常這意味着有一些剩餘的位,最後一個字符有一些空間可供播放。但只有一點,只在最後一個字符。

+0

感謝您的回覆。我的加密文本是xJzgOiMzimNOY6UsB + TNw9gUmcpdiZxQq70FxwbmkCc =,我將最後兩個字符(c =)修改爲d =,並試圖解密xJzgOiMzimNOY6UsB + TNw9gUmcpdiZxQq70FxwbmkCd =。我聽說=是填充,但爲什麼當我改變另一個字符時,我能夠解密字符串。 –

+1

剝離加密部分。你的問題是關於Base64的。它有一些內置的冗餘。 –

+0

非常感謝。 –

1

除了說什麼,你需要認識到,低級別的加密和解密只是一個轉變。它不知道輸入和輸出是什麼以及它應該是什麼。即如果你加密16個字節,修改第5個字節並將這16個字節解密回來,你會得到與你加密的數據不相符的輸出,但你也不會得到錯誤。

對於要檢測到的更改,您需要使用某種完整性檢查。這通常在高級加密方案中完成,例如OpenPGP或CMS或SSL/TLS和SSH等協議。