I have a triple DES wrapper in C# that consists of two static functions, Encrypt
and Decrypt
. Occasionally, Decrypt
fails with TransformFinalBlock(..., ...)
throwing the error 'Bad data'.
Thanks in advance.
public static string Encrypt(string toencrypt, string key, bool usehashing = true)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toencrypt);
byte[] resultArray;
//If hashing use get hashcode regards to your key
if (usehashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//Always release the resources and flush data
// of the Cryptographic service provide. Best Practice
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes.
//We choose ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
try
{
//transform the specified region of bytes array to resultArray
resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
}
catch (System.Exception ex)
{
//Release resources held by TripleDes Encryptor
tdes.Clear();
return "";
}
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string todecrypt, string key, bool usehashing = true)
{
byte[] keyArray;
byte[] toEncryptArray;
byte[] resultArray;
//get the byte code of the string
try
{
toEncryptArray = Convert.FromBase64String(todecrypt.Replace(" ", "+"));//The replace happens only when spaces exist in the string (hence not a Base64 string in the first place).
}
catch (System.Exception ex)
{
return "";
}
if (usehashing)
{
//if hashing was used get the hash code with regards to your key
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//release any resource held by the MD5CryptoServiceProvider
hashmd5.Clear();
}
else
{
//if hashing was not implemented get the byte code of the key
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes.
//We choose ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
try
{
resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
}
catch (System.Exception ex)
{
//Release resources held by TripleDes Encryptor
tdes.Clear();
return "";
}
//Release resources held by TripleDes Encryptor
tdes.Clear();
//return the Clear decrypted TEXT
return UTF8Encoding.UTF8.GetString(resultArray);
}
An example string that once encrypted causes Decrypt
to fail would be:
AgAAAA* AQAAAA *aAAAAA* jfgGTw *nY+sHZ2PrBmdj6wVnY+sEZ2PrA2dj6wFk4GhCJOHoQqdj6x9nY+seQ* trIBAA *AAMAAA**+L7PHiJ76M8OTV4BjXCkuDgDG2u7AcW87p1KU7KTSCKI3fYTnYAcGk1gyS62AvZO4g1FrsVbzoAnsX9Y0Ju+V9YjaYr9+Xr+pen4SEas0NjRvntv0gqU0QZOj9bjKXx1Izc9Dw1HCUqjUGBcwakQo6kBlvb2v2/pV9dM4B3RM6m7rmaW79CSc7CC3DQjnqA5HMHC5k65pOK0KT76MzTawYQotNOk0BabTO3HpVcI8BNNjSsIP7TvtxXBmbc6TfXahw1zLTvC4iTSPnsgz0jhxvHhHD+N0cblfQhAK/nt2IZQuWGL3jW0oPpPJnjhGMWQPDLXbNwp23WUv8GXIPKevXbushYKjutmsdqJT7C1mcB45XhbYCVUVbLIja1AV831YeHqqke2msSaisg37UM+urL9EFIueUHZgZryhQUSjAhZDiHXqosoQou92RqbTK5YTqYY+zyBBzRt2r7KS3v5u9smtWMNk8Xcn42a6pFFxd6g4u0/s/SVm7NFb2UbREvp75lBVxEQv5IIznPSHfDnLtuX8pLfrZ/AVQ+gM9AGvzBjHGNYDQJ6VhgkHOZMeuLISJXjfGX0ZPFYKd+CPObpbFlukOSlIB5epRDnuggTLnthpN06Kle+iDqz1Q96ty4mfzwuhRwxvQ7EMzTykHXxC8p9bLKMr86K/vart2D9w1g9RtyS+pekgW8lkutWWGdu1eZml/5abNmlW5VgSJiuA9Yyrd2UNjUl6/a0oMKHPk6b2gZkpmENpO7auC9HA2gO
However most strings do not cause it to fail. This must be something to do with special characters I'm guessing.
First, please provide the initial unencrypted key and string which generates that encrypted block that fails. Then we may have a better chance of figuring out why there's an issue. However, that being requested, I see a few potential pitfalls in your code, mostly related to not disposing of types which implement IDisposable
. Here's a small refactoring of the code which takes that into account (amongst a few other small adjustments):
public static string Encrypt(string toencrypt, string key, bool usehashing = true)
{
byte[] keyArray;
// If hashing use get hash code regards to your key
if (usehashing)
{
using (var hashmd5 = new MD5CryptoServiceProvider())
{
keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));
}
}
else
{
keyArray = Encoding.UTF8.GetBytes(key);
}
// set the secret key for the tripleDES algorithm
// mode of operation. there are other 4 modes.
// We choose ECB(Electronic code Book)
// padding mode(if any extra byte added)
using (var tdes = new TripleDESCryptoServiceProvider
{
Key = keyArray,
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
})
using (var transform = tdes.CreateEncryptor())
{
try
{
var toEncryptArray = Encoding.UTF8.GetBytes(toencrypt);
// transform the specified region of bytes array to resultArray
var resultArray = transform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
// Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
catch (Exception)
{
return string.Empty;
}
}
}
public static string Decrypt(string todecrypt, string key, bool usehashing = true)
{
byte[] toEncryptArray;
// get the byte code of the string
try
{
toEncryptArray = Convert.FromBase64String(todecrypt.Replace(" ", "+")); // The replace happens only when spaces exist in the string (hence not a Base64 string in the first place).
}
catch (Exception)
{
return string.Empty;
}
byte[] keyArray;
if (usehashing)
{
// if hashing was used get the hash code with regards to your key
using (var hashmd5 = new MD5CryptoServiceProvider())
{
keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));
}
}
else
{
// if hashing was not implemented get the byte code of the key
keyArray = Encoding.UTF8.GetBytes(key);
}
// set the secret key for the tripleDES algorithm
// mode of operation. there are other 4 modes.
// We choose ECB(Electronic code Book)
// padding mode(if any extra byte added)
using (var tdes = new TripleDESCryptoServiceProvider
{
Key = keyArray,
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
})
using (var transform = tdes.CreateDecryptor())
{
try
{
var resultArray = transform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
// return the Clear decrypted TEXT
return Encoding.UTF8.GetString(resultArray);
}
catch (Exception)
{
return string.Empty;
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.