2012-05-28 49 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