Encrypt and Decrypt password - c#

I am using the following code to encrypt and decrypt passwords in asp.net. the encryption works perfectly but when decrypting it throws this error Invalid length for a Base-64 char array.
my password is 123 and i am using it as follow to encrypt: HttpUtility.UrlEncode(CryptorEngine.Encrypt(strpassword, true));
and to decrypt I am using it as follow :
CryptorEngine.Decrypt(HttpUtility.UrlDecode(strpassword), true));
and here is the code :
public class CryptorEngine
{
/// <summary>
/// Encrypt a string using dual encryption method. Return a encrypted cipher Text
/// </summary>
/// <param name="toEncrypt">string to be encrypted</param>
/// <param name="useHashing">use hashing? send to for extra secirity</param>
/// <returns></returns>
public static string Encrypt(string toEncrypt, bool useHashing)
{
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("SecurityKey", typeof(String));
//System.Windows.Forms.MessageBox.Show(key);
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);
}
/// <summary>
/// DeCrypt a string using dual encryption method. Return a DeCrypted clear string
/// </summary>
/// <param name="cipherString">encrypted string</param>
/// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param>
/// <returns></returns>
public static string Decrypt(string cipherString, bool useHashing)
{
byte[] keyArray;
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("SecurityKey", typeof(String));
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);
}
}

In the URL there are come characters that conflict with the encrypted output, and at least on my code, this is what make the problem. So I use this two functions to change this characters and avoid that.
public static string ChangeSPChart(string sTheInput)
{
StringBuilder sRetMe = new StringBuilder(sTheInput);
sRetMe.Replace('+', '-');
sRetMe.Replace('/', '*');
sRetMe.Replace('=', '!');
return sRetMe.ToString();
}
public static string FixSPChart(string sTheInput)
{
StringBuilder sRetMe = new StringBuilder(sTheInput);
sRetMe.Replace('-', '+');
sRetMe.Replace('*', '/');
sRetMe.Replace('!', '=');
return sRetMe.ToString();
}
and the encryption/decryption code will be:
public static string Encrypt(string toEncrypt, bool useHashing)
{
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("SecurityKey", typeof(String));
//System.Windows.Forms.MessageBox.Show(key);
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();
var encrypted = Convert.ToBase64String(resultArray, 0, resultArray.Length);
// here I change it
return ChangeSPChart(encrypted);
}
/// <summary>
/// DeCrypt a string using dual encryption method. Return a DeCrypted clear string
/// </summary>
/// <param name="cipherString">encrypted string</param>
/// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param>
/// <returns></returns>
public static string Decrypt(string cipherString, bool useHashing)
{
cipherString = FixSPChart(cipherString);
byte[] keyArray;
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("SecurityKey", typeof(String));
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);
}

hiii please use this code this works good
//Encryption method for credit card
public string EncryptTripleDES(string Plaintext, string Key)
{
System.Security.Cryptography.TripleDESCryptoServiceProvider DES =
new System.Security.Cryptography.TripleDESCryptoServiceProvider();
System.Security.Cryptography.MD5CryptoServiceProvider hashMD5 =
new System.Security.Cryptography.MD5CryptoServiceProvider();
DES.Key = hashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(Key));
DES.Mode = System.Security.Cryptography.CipherMode.ECB;
System.Security.Cryptography.ICryptoTransform DESEncrypt = DES.CreateEncryptor();
Buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(Plaintext);
string TripleDES = Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
return TripleDES;
}
//Decryption Method
public string DecryptTripleDES(string base64Text, string Key)
{
System.Security.Cryptography.TripleDESCryptoServiceProvider DES =
new System.Security.Cryptography.TripleDESCryptoServiceProvider();
System.Security.Cryptography.MD5CryptoServiceProvider hashMD5 =
new System.Security.Cryptography.MD5CryptoServiceProvider();
DES.Key = hashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(Key));
DES.Mode = System.Security.Cryptography.CipherMode.ECB;
System.Security.Cryptography.ICryptoTransform DESDecrypt = DES.CreateDecryptor();
Buffer = Convert.FromBase64String(base64Text);
string DecTripleDES = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));
return DecTripleDES;
}

The code you have provided works fine. I tested it with this little program:
void Main()
{
var cryptB64 =CryptorEngine.Encrypt("123", true);
var encoded = HttpUtility.UrlEncode(cryptB64);
var decoded = HttpUtility.UrlDecode(encoded);
var decrypted = CryptorEngine.Decrypt(decoded, true);
bool matches = (decrypted=="123");
Console.WriteLine(matches);
}
And it returned true as expected.
The problem is presumably that you are mangling your encrypted value at some point. I would guess it is being transmitted via HTTP which I would guess is where the problem happens.
Additional Note:
When calling CryptorEngine.Decrypt(HttpUtility.UrlDecode(strpassword), true)); then you need to make sure that strpassword is the encrypted form of the password, not the plaintext password you are comparing against.

A little late here but the problem could be something else (it was for me).
Request.Querystring does some decoding already. In my case I was essentially decoding twice. Adding a second "HttpUtility.UrlEncode" did the trick (at least after 20 different tests).
I haven't exactly found firm documentation from Microsoft on this behavior, and the old books are stored away (I try not to leave my chair), but these links were helpful:
does Request.Querystring automatically url decode a string?
http://forums.asp.net/t/1354726.aspx?Request+Querystring+without+decoding+possible+

Related

TRIPLE DES ECB Encryption RUBY

I have a sample code in .NET C# which I need to convert to RUBY.
public static string Encrypt(string pstrText)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(pstrText);
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(secKey));
hashmd5.Clear();
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);
}
I have tried using OPENSSL:CIPHER and got thus far -
def encrypt data
secret = "******************"
md5 = Digest::MD5.hexdigest(secret)
des = OpenSSL::Cipher::Cipher.new 'DES-EDE3'
des.encrypt
des.key = md5
update_value = des.update(data)
up_final = update_value + des.final
puts Base64.encode64(up_final).gsub(/\n/, "")
end
The results in C# and RUBY do not match. Where am I going wrong?

Encryption and Decryption in C# using MD5CryptoServiceProvider

I have a service named CryptoService which inherit the interface ICryptoService that consist of 2 method Crypto Decrypto function.
Encryption of a string is Working but the Decryption of hash result will return my key instead of the Decrypted string.
Here is my encryption code :
private string _salt = "*1234567890!##$%^&*()14344*";
private string Crypto(string text)
{
var hashmd5 = new MD5CryptoServiceProvider();
byte[] toEncryptArray = Encoding.UTF8.GetBytes(_salt);
byte[] keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_salt));
hashmd5.Clear();
TripleDesProvider.Key = keyArray;
TripleDesProvider.Mode = CipherMode.ECB;
TripleDesProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDesProvider.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
My decryption code :
private string Decrypto(string text)
{
try
{
var hashmd5 = new MD5CryptoServiceProvider();
byte[] toEncryptArray = Convert.FromBase64String(text);
byte[] keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(_salt));
hashmd5.Clear();
TripleDesProvider.Key = keyArray;
TripleDesProvider.Mode = CipherMode.ECB;
TripleDesProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = TripleDesProvider.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
TripleDesProvider.Clear();
return Encoding.UTF8.GetString(resultArray);
//return Encoding.UTF8.GetString(resultArray);
}
catch
{
return string.Empty;
}
}
provided here the screenshot in action.
here are the references of my codes I found in the internet
https://www.codeproject.com/Articles/14150/Encrypt-and-Decrypt-Data-with-C
This cannot work. A hash, such as MD5, is one-way. You cannot get the original text from the hash value.
If your crypto service runs on the same machine, I suggest using the Data Protection class.
Your toEncryptArray in Encrypto gets the value _salt. You meant text.
So, good news, your decryption works.

PHP Triple DES encryption and compatible C# decryption

I am decrypting a message in C#, this message is encrypted in PHP using below code:-
public function __construct($sEncryptionKey)
{
$this->link = mcrypt_module_open('tripledes', '', 'ecb', '');
$this->sInitializationVector = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->link), MCRYPT_RAND);
$this->iKeySize = mcrypt_enc_get_key_size($this->link);
$sEncryptionKey = substr(md5($sEncryptionKey), 0, $this->iKeySize);
mcrypt_generic_init($this->link, $sEncryptionKey, $this->sInitializationVector);
}
public function encrypt($sDataToEncrypt)
{
return base64_encode(mcrypt_generic($this->link, $sDataToEncrypt));
}
And I am using below decryption function in c# for decryption:-
public string Decrypt(string toDecrypt, string key, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
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.Zeros;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
var strValue = UTF8Encoding.UTF8.GetString(resultArray);
return UTF8Encoding.UTF8.GetString(resultArray);
}
I tried with few changes and getting below results:-
1.) PaddingMode.PKCS7 with no hashing = "Specified key is not a valid size for this algorithm."
2.) PaddingMode.PKCS7 with hashing = "Bad Data."
3.) PaddingMode.Zeros with no hashing = "Specified key is not a valid size for this algorithm."
4.) PaddingMode.Zeros with hashing = "�8�f����q6IGs�" some unknown characters
I think 4'th one will work, but not sure what I am doing wrong.
Found a solution, need to do changes in MD5 hashing, below are whole code if someone stuck in same situation :-
public string Decrypt(string toDecrypt, string key, bool useHashing)
{
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
byte[] keyArray;
byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
string keyArrayStr = "";
if (useHashing)
{
MD5 md5 = MD5CryptoServiceProvider.Create();
byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(key));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < dataMd5.Length; i++)
sb.AppendFormat("{0:x2}", dataMd5[i]);
keyArrayStr = sb.ToString().Substring(0, tdes.Key.Length);
keyArray = UTF8Encoding.UTF8.GetBytes(keyArrayStr);
}
else
{
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.Zeros;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
var strValue = UTF8Encoding.UTF8.GetString(resultArray);
return UTF8Encoding.UTF8.GetString(resultArray);
}

C# FromBase64String fail due to unknown UNICODE

I have an encrypted database in which the strings are values like the below:
ùœ¢Qa³•ù¼?-pJ´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
ù¢=~Òñ€Ï?-pJ´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
XwÚûùÖP^opJ´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
ö‘±_|Çúùß^_f9´’ˆò»Æ8-skYIÞµ§¬†Œ‚„Šç
I'm trying different ways to dencrypt the information (it's a simmetric encryption and I have the key, but I don't know the algorithm, more detail here How to decrypt a string encrypted by V FoxPro)
When I tried different ways to dencrypt using C#.NET in an step I get àn error saying that "the string has a non-base64 character" in the following line:
Convert.FromBase64String(input)
Where input is a string similar to the one I share above.
How Can I receive an string like that from DB in order to work with that in C#?
I normally use something like this:
public static class EncryptDecryptString
{
public static string Encrypt(string input, string key)
{
byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string input, string key)
{
byte[] inputArray = Convert.FromBase64String(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
}

Invalid length for Convert.FromBase64String

So I'm trying to decrypt an encrypted string, it encrypts fine, and sometimes decrypts it if I'm lucky enough but usually the string length is too long.. firstly here is the code where I called the decryption method
decrypted = Decrypt(recieved, getString(anarchyAes.Key));
addToChat(decrypted);
recieved is just the encrypted string, and the other parameter is the decryption key. Here is the Decrypt method..
public static string Decrypt(string cipherString, string securityKey)
{
var key = securityKey;
var keyArray = Encoding.UTF8.GetBytes(key);
var tdes = new TripleDESCryptoServiceProvider
{
Key = keyArray,
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
var cTransform = tdes.CreateDecryptor();
var toEncryptArray = Convert.FromBase64String(cipherString);
var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Encoding.UTF8.GetString(resultArray);
}
It fails when it does
var toEncryptArray = Convert.FromBase64String(cipherString);
When the string is more than 7 characters giving the error, invalid length for a 64 base string. I'm wondering how I could possibly fix this, any insight is appreciated.
Encrpytion code:
public static string Encrypt(string toEncrypt, string securityKey)
{
var key = securityKey;
var keyArray = Encoding.UTF8.GetBytes(key);
var tdes = new TripleDESCryptoServiceProvider
{
Key = keyArray,
Mode = CipherMode.ECB,
Padding = PaddingMode.PKCS7
};
var cTransform = tdes.CreateEncryptor();
var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);
var resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

Categories