我正在开发一个通过.Net的mvc应用程序,以保护我的敏感信息,例如web.config中的信息 我有两个使用Triple 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);
}
TripleDES 算法指定一个 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 与密文一起存储。
我最近遇到了这个问题。空值已传递给Decrypt()
。如果Message
(要解密的数据)为空,则TransformFinalBlock()
(Decrypt()
内部)会引发错误数据异常。
因此,请在调用Decrypt()
之前为要解密的数据添加空/空检查。