2012-05-28 47 views
1

我正在通過.Net處理mvc應用程序,以確保我的敏感信息(如web.config中的信息)的安全我有兩個函數使用三重DES加密和解密信息,然而,我是新來的,併成功通過朋友的幫助達成。使用三重DES解密信息時出現錯誤數據

加密功能工作正常但是並返回我回到正確的字符串時,我試圖解密我得到這條線上的解密功能的

Exception Details: System.Security.Cryptography.CryptographicException: Bad Data.

錯誤相同的字符串:

Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);

我試圖去解決它在我列爲註釋代碼幾種方法,但他們並沒有幫助,請幫我出這一點。

public static string Encrypt(string Message, string Passphrase) 
    { 
     byte[] Results; 
     System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
     MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
     byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase))); 
     TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
     TDESAlgorithm.Key = TDESKey; 
     TDESAlgorithm.Mode = CipherMode.ECB; 
     TDESAlgorithm.Padding = PaddingMode.PKCS7; 
     byte[] DataToEncrypt = UTF8.GetBytes(Message); 
     try 
     { 
      ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor(); 
      Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length); 
     } 
     finally 
     { 
      TDESAlgorithm.Clear(); 
      HashProvider.Clear(); 
     } 
     return Convert.ToBase64String(Results); 
     //return Encoding.UTF8.GetString(Results); 

    } 

    public static string Decrypt(string Message, string Passphrase) 
    { 
     byte[] Results; 
     System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
     MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
     byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase))); 
     TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
     TDESAlgorithm.Key = TDESKey; 
     TDESAlgorithm.Mode = CipherMode.ECB; 
     TDESAlgorithm.Padding = PaddingMode.PKCS7; 
     try 
     { 
      byte[] DataToDecrypt = Convert.FromBase64String(Message); 
      //byte[] DataToDecrypt = UTF8.GetBytes(Message); 
      //byte[] DataToDecrypt = Encoding.UTF8.GetBytes(Message); 
      ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor(); 
      Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length); // << ERROR is here. 
     } 
     finally 
     { 
      TDESAlgorithm.Clear(); 
      HashProvider.Clear(); 
     } 
     return UTF8.GetString(Results); 
    } 

回答

6

的TripleDes的算法指定其用來確保同一數據的反覆加密使用相同的密鑰產生不同的加密文本的IV(初始化向量)。要成功解密,必須在解密過程中使用與加密過程中使用的IV相同的IV。

由於您當前沒有在執行加密時指定IV(TDESAlgorithm.IV),因此該算法將其設置爲隨機值。該算法還將解密期間使用的IV設置爲隨機值(但與加密中使用的不同),因此解密過程失敗。

要糾正你可以使用下面的(注意,在加密階段隨機產生的IV是從Encrypt方法輸出並傳遞給Decrypt方法)問題:

public static string Encrypt(string Message, string Passphrase, out byte[] iv) 
{ 
    byte[] Results; 
    System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
    MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
    byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase))); 
    TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
    TDESAlgorithm.Key = TDESKey; 
    TDESAlgorithm.Mode = CipherMode.ECB; 
    TDESAlgorithm.Padding = PaddingMode.PKCS7; 
    // Capture the randomly generated IV 
    iv = TDESAlgorithm.IV; 
    byte[] DataToEncrypt = UTF8.GetBytes(Message); 
    try 
    { 
     ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor(); 
     Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length); 
    } 
    finally 
    { 
     TDESAlgorithm.Clear(); 
     HashProvider.Clear(); 
    } 
    return Convert.ToBase64String(Results); 
    //return Encoding.UTF8.GetString(Results); 
} 

public static string Decrypt(string Message, string Passphrase, byte[] iv) 
{ 
    byte[] Results; 
    System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding(); 
    MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider(); 
    byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase))); 
    TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider(); 
    TDESAlgorithm.Key = TDESKey; 
    // Apply the same IV used during encryption 
    TDESAlgorithm.IV = iv; 
    TDESAlgorithm.Mode = CipherMode.ECB; 
    TDESAlgorithm.Padding = PaddingMode.PKCS7; 
    try 
    { 
     byte[] DataToDecrypt = Convert.FromBase64String(Message); 
     //byte[] DataToDecrypt = UTF8.GetBytes(Message); 
     //byte[] DataToDecrypt = Encoding.UTF8.GetBytes(Message); 
     ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor(); 
     Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length); // << ERROR is here. 
    } 
    finally 
    { 
     TDESAlgorithm.Clear(); 
     HashProvider.Clear(); 
    } 
    return UTF8.GetString(Results); 
} 

請注意,您將需要如果您以後要成功解密數據,請將IV與密文一起存儲。

+0

通常在傳輸之前將IV添加到實際密文的前面,以便接收端獲得副本。解密時,只需先閱讀IV,然後用它來解密輸入流的其餘部分。 – rossum

+0

@Iridium&@rossum:謝謝你這麼明確的答案,先生,只有你說的幾件事,我應該在加密字符串的末尾加上'iv',所以你能告訴我怎樣連接兩個字節[]變量我試着這個'結果=結果+ iv;'但它當然不工作? – Maven

+0

IV應在加密字節的_start_處進行,因爲您的收件人將需要它開始加密。在C#中連接數組請參見http://stackoverflow.com/questions/415291/best-way-to-combine-two-or-more-byte-arrays-in-c-sharp – rossum