Special characters in MD5 encryption - c#

I'm having a problem with MD5 encryption in C# and SQL Server, it only happens on rows with special characters.
Here is the Code in c#:
public virtual string RowHash<T>(T item)
{
PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
var finalvalue = "";
foreach (PropertyInfo p in properties)
{
if (p.Name != "Hash")
{
if (!p.CanWrite || !p.CanRead) { continue; }
MethodInfo mget = p.GetGetMethod(false);
MethodInfo mset = p.GetSetMethod(false);
// Get and set methods have to be public
if (mget == null) { continue; }
if (mset == null) { continue; }
var value = p.GetValue(item, null) == null ? "" : p.GetValue(item, null) is Entity? ((Entity)p.GetValue(item, null)).Id.ToString() : p.GetValue(item, null).ToString();
finalvalue += value;
}
}
return finalvalue;
}
public static string GetMD5(string text)
{
var md5 = MD5CryptoServiceProvider.Create();
var encoding = new ASCIIEncoding();
byte[] stream = null;
var sb = new StringBuilder();
stream = md5.ComputeHash(encoding.GetBytes(text));
for (int i = 0; i < stream.Length; i++) sb.AppendFormat("{0:x2}", stream[i]);
return sb.ToString();
}
public static string PasswordMD5(string password)
{
var pwd = GetMD5(password + GetMD5(password).Substring(0,2));
return pwd;
}
With the method RowHash I get concatenated all the fields from the Row unless the field hash that will store the result, then I sent it to the method PasswordMD5 that creates the encrypted Hash we save in the database.
Then I do the same in SQL Server with this code:
CONVERT(VARCHAR(32), HashBytes('MD5',CONVERT(VARCHAR(MAX),CONVERT(VARCHAR(MAX),ISNULL([Field1],''))+ISNULL([Field2],'')+ISNULL([Field3],'')+CONVERT(VARCHAR(MAX),ISNULL([Field4],''))+ISNULL(CONVERT(VARCHAR(MAX),[Field5]),'')+ISNULL(CONVERT(VARCHAR(MAX),Field6]),'')+CONVERT(VARCHAR(MAX),Field7]))+SUBSTRING(CONVERT(VARCHAR(32),HashBytes('MD5',CONVERT(VARCHAR(MAX),CONVERT(VARCHAR(MAX),ISNULL([Field1],''))+ISNULL([Field2],'')+ISNULL([Field3],'')+CONVERT(VARCHAR(MAX),ISNULL([Field4],''))+ISNULL(CONVERT(VARCHAR(MAX),Field5]),'')+ISNULL(CONVERT(VARCHAR(MAX),[Field6]),'')+CONVERT(VARCHAR(MAX),Field7]))) 2), 1, )), 2)
Then I compare this with the Hash that I created in C# to check the integrity of the data I have in the database. This works perfectly fine for all the rows without special characters, but fail for all the rows that contain any special characters like é or ö.
This is an issue I faced some time ago, but the task was paused by other priorities, I don't remember exactly what solutions I already tried, I remember that I tried some solutions changing the encoding of the strings in C# but none worked.
What I am doing wrong?
Thanks in advance.

Finally I cannot find a good solution using MD5, I moved to SHA256 and it worked using this answer:
https://stackoverflow.com/a/19214122/4890862

I Use this Encrypt and Decrypt method for my code and i already tested with special character and its work fine for me. i will send you my code plz test this once i hope it will work you.
TableFilter Is common class file which file contains encrypt and decrypt method nothing else you can write these two method on .cs page.
public static string Encrypt(string toEncrypt, bool useHashing = true)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
System.Configuration.AppSettingsReader settingsReader =
new AppSettingsReader();
// Get the key from config file
string key = (string)settingsReader.GetValue("EncryptionKey",
typeof(String));
//System.Windows.Forms.MessageBox.Show(key);
//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();
//transform the specified region of bytes array to resultArray
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0,
toEncryptArray.Length);
//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 cipherString, bool useHashing = true)
{
byte[] keyArray;
//get the byte code of the string
byte[] toEncryptArray = Convert.FromBase64String(cipherString);
System.Configuration.AppSettingsReader settingsReader =
new AppSettingsReader();
//Get your key from config file to open the lock!
string key = (string)settingsReader.GetValue("EncryptionKey",
typeof(String));
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();
byte[] resultArray = cTransform.TransformFinalBlock(
toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//return the Clear decrypted TEXT
return UTF8Encoding.UTF8.GetString(resultArray);
}
: For textbox string (instead of txtpassword.text put testingé123ö for Understanding))
login_Model.Password = TableFilter.Encrypt("testingé123ö");
: Web.config
<add key="EncryptionKey" value="encyptionkeyvalue"/>

Related

How to triple des C# method according to swift method

How to change C# encryption method to the same as swift? I tried below code, but it's converting the string different. I want according to same as swift due to decryption method. I am using 3des. My C# method encrypt/decrypt is working fine.
I want same as C# in Swift.
C#
public static string Encrypt(string PlainText)
{
try
{
if (PlainText.Length > 0)
{
string key = "FIFEDCBA98765432104AABFD";
byte[] PlainTextArray = UTF8Encoding.UTF8.GetBytes(PlainText);
byte[] keyArray = MD5.CreateMd5ByteArray(key);
TripleDESCryptoServiceProvider TripleDes = new TripleDESCryptoServiceProvider();
TripleDes.Key = keyArray;
TripleDes.Mode = CipherMode.ECB;
TripleDes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDes.CreateEncryptor();
byte[] CipherString = cTransform.TransformFinalBlock(PlainTextArray, 0, PlainTextArray.Length);
TripleDes.Clear();
return Convert.ToBase64String(CipherString, 0, CipherString.Length);
}
else
{
return null;
}
}
catch (Exception ex)
{
throw;
}
}
SWIFT
func tripleDesEncrypt(PlainString: String) -> String{
let keyData = "FIFEDCBA98765432104AABFD"
let PlainStringvar = PlainString
guard let data = PlainStringvar.data(using: .utf8) else {
return ""
}
let cryptData = NSMutableData(length: Int(data.count) + kCCBlockSize3DES)!
let keyLength = size_t(kCCKeySize3DES)
let operation: CCOperation = UInt32(kCCEncrypt)
let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES)
let options: CCOptions = UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding)
var numBytesEncrypted :size_t = 0
let cryptStatus = CCCrypt(operation,
algoritm,
options,
keyData.bytes, keyLength,
nil,
data.bytes, data.count,
cryptData.mutableBytes, cryptData.length,
&numBytesEncrypted)
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.length = Int(numBytesEncrypted)
var base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
return base64cryptString//// encodeString(str: base64cryptString)
} else {
print("Error: \(cryptStatus)")
}
return ""
}
Your problem in C# appears to be this line:
byte[] keyArray = MD5.CreateMd5ByteArray(key);
Assuming that function (which is not part of the .NET BCL, so I assume it's something custom that you wrote) creates an MD5 hash of your 3DES key, that's the only difference between your C# and Swift versions.
In Swift, you encrypt the value using a key which is the UTF-8 encoded value of "FIFE...".
In C#, you encrypt the value using a key which is the MD5 hash of the UTF-8 encoded value if "FIFE...".
If you replace that line with the following one:
var keyArray = Encoding.UTF8.GetBytes(key);
then both functions return the same ciphertext for the same plaintext values.

How can i edit my code so that the exceptions while decryption can end

Exception Occuring:
System.Security.Cryptography.CryptographicException' occurred in
mscorlib.dll Additional details:: Length of the data to decrypt is
invalid.
public string Encrypt(string toEncrypt, bool useHashing)
{
toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
System.Configuration.AppSettingsReader settingsReader = new System.Configuration.AppSettingsReader();
// Get the key from config file
//string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
//string key = UTF8Encoding.UTF8.GetString(keyArray);
////System.Windows.Forms.MessageBox.Show(key);
////If hashing use get hashcode regards to your key
//keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
try
{
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;
iv = tdes.IV;
ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
catch (Exception ae)
{
MessageBox.Show(ae.Message);
return ae.Message;
}
}
public string Decrypt(string cipherString, bool useHashing)
{
//get the byte code of the string
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(cipherString);
System.Configuration.AppSettingsReader settingsReader = new System.Configuration.AppSettingsReader();
//Get your key from config file to open the lock!
//string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
string key = UTF8Encoding.UTF8.GetString(keyArray);
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;
tdes.IV=iv;
//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();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
//string s=resultArray.ToString("X2");
tdes.Clear();
//return the Clear decrypted TEXT
return UTF8Encoding.UTF8.GetString(resultArray);
}
Your Encrypt() method returns the encrypted bytes converted to a Base64 string. Your Decrypt() method tries to decrypt the Base64 string directly:
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(cipherString);
Instead you need to convert the Base64 string back to bytes using a Base64 conversion:
byte[] toEncryptArray = Convert.FromBase64String(cipherString);

Getting Bad Data exception during decryption (using .Net Cryptography)

I am using symmetric TripleDES encryption from the class TripleDESCryptoServiceProvider (.Net 2.0) to encrypt the contents of a file.
The data gets encrypted perfectly but during decryption it throws the CryptographyException: Bad data
I am using key from current date time and IV from the randomly generated value by .Net class. Then I pass the same key and IV to the decryption method but it fails for some reason.
Here is my code :
static void Main(string[] args){
string fileName = "input.exe";
string newFileName = fileName + "crypted.exe";
byte[] iv;
var fileToEncrypt = File.ReadAllBytes(fileName);
var encryptionKey = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(DateTime.Now.ToString("ddMMyyHmmss")));
File.WriteAllBytes(newFileName, EncryptTripleDES(fileToEncrypt, encryptionKey, out iv));
File.WriteAllBytes(fileName + "decrypted.exe", DecryptTripleDES(File.ReadAllBytes(newFileName), encryptionKey,iv));
}
public static byte[] EncryptTripleDES(byte[] dataToEncrypt, byte[] key, out byte[] iv){
byte[] result;
var tdes = new TripleDESCryptoServiceProvider { Key = key, KeySize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 };
iv = tdes.IV;
using(ICryptoTransform cTransform = tdes.CreateEncryptor()){
result = cTransform.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
tdes.Clear();
}
return result;
}
public static byte[] DecryptTripleDES(byte[] dataToDecrypt, byte[] key, byte[] iv){
byte[] result;
var tdes = new TripleDESCryptoServiceProvider { Key = key, KeySize = 128, Mode = CipherMode.CBC,IV = iv,Padding = PaddingMode.PKCS7 };
using (ICryptoTransform cTransform = tdes.CreateDecryptor()){
result = cTransform.TransformFinalBlock(dataToDecrypt, 0, dataToDecrypt.Length);
tdes.Clear();
}
return result;
}
UPDATE:
1. I have checked the value of IV being passed is valid and same as used in encryption.
2. Changing the padding to zero or none doesn't raise the exception but then the data isn't decrypted correctly. It comes out to be different than original.
The problem is in the way that you're constructing the TripleDESCryptoServiceProviders using an initializer. The Key is set first in the initializer, but then you set the KeySize, which causes the Key to be reset to a new (randomly generated) key, as a result, you're encrypting and decrypting with different keys (neither of which are the key you generate).
You can fix this by re-ordering the initializer so that KeySize is set first, or perhaps move the setting of the Key outside the initializer entirely to avoid any ambiguity:
public static byte[] EncryptTripleDES(byte[] dataToEncrypt, byte[] key, out byte[] iv){
byte[] result;
var tdes = new TripleDESCryptoServiceProvider { KeySize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 };
// Key explicitly set here, not in the initializer:
tdes.Key = key;
iv = tdes.IV;
using(ICryptoTransform cTransform = tdes.CreateEncryptor()){
result = cTransform.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
tdes.Clear();
}
return result;
}
public static byte[] DecryptTripleDES(byte[] dataToDecrypt, byte[] key, byte[] iv){
byte[] result;
var tdes = new TripleDESCryptoServiceProvider { KeySize = 128, Mode = CipherMode.CBC,IV = iv,Padding = PaddingMode.PKCS7 };
// Key explicitly set here, not in the initializer:
tdes.Key = key;
using (ICryptoTransform cTransform = tdes.CreateDecryptor()){
result = cTransform.TransformFinalBlock(dataToDecrypt, 0, dataToDecrypt.Length);
tdes.Clear();
}
return result;
}

How to store a system.net.mail password in the database

I need to store email passwords which will be used with system.net.mail. These need to be retrieved and sent as plain text but I don't want to store them as plain text. This isn't really about security as its for an intranet and I just don't want the results being displayed in plain text in the CMS.
I've read plenty of articles saying that storing password should be done using SHA1. From what I've read hashing is no good because the plain text cant be retrieved.
I am currently trying this methods:
public static string EncodePasswordToBase64(string password)
{
try
{
byte[] encData_byte = new byte[password.Length];
encData_byte = System.Text.Encoding.UTF8.GetBytes(password);
string encodedData = Convert.ToBase64String(encData_byte);
return encodedData;
}
catch (Exception ex)
{
throw new Exception("Error in base64Encode" + ex.Message);
}
}
and
public static string DecodeFrom64(string encodedData)
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(encodedData);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char);
return result;
}
but I cant seem to find the correct data type in my database to store the value. Its currently set to nvarchar(MAX).
The cell contents display like this (with spaces between each value):
Q X B j L W V w M X B =
Strangely when I click and enter the cell to copy the data all I get is:
Q
What data type should I use for this column?
You can use something like this..
//For encrypting string.
public static string Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
string key = "UglyRandomKeyLike-lkj54923c478";
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
// To decrypt string
public static string Decrypt(string cipherString, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(cipherString);
string key = "UglyRandomKeyLike-lkj54923c478";
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
The above mentioned method will encrypt your password and you can store it in varchar field in your database. The second method takes encrypted password and return it in normal string
I hope this is what you are looking for.. I am not able to comment in your question.
Well, you're correct that hashing is not the correct way to go. What you actually want to use is Symmetric Encryption which will allow you to encrypt the data in the DB but then to decrypt it back in your main program.
AES is the recommended standard. Here is an example of how it used in C#.
I'd read a little bit more about how to correctly choose an IV to avoid common pitfalls.

C# triple DES wrapper problems: TransformFinalBlock throws 'Bad data'

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'.
Why is this happening?
What's the solution?
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;
}
}
}

Categories

Resources