Reputation: 39
I want encrypt in C# and decrypt in c++ but I have some Encoding problem :
example variables :
Key : gOtIPaLver—vS5UAnJbPqsDZSf,yJ1 IVString : gOtIPaLver—vS5
my c# code :
public static string EncryptString(string message, string KeyString, string IVString)
{
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString.Substring(0,32));
byte[] IV = UTF8Encoding.UTF8.GetBytes(IVString);
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
rj.Padding = PaddingMode.PKCS7;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}
When I try encrypt and my Key have some not ASCII char - count of bytes is more than lenght of string .
How Encoding I shound use ? In C++ I use EVP (default padding is PKCS7) .
static string decryptEX(string KS, string ctext)
{
EVP_CIPHER_CTX* ctx;
ctx = EVP_CIPHER_CTX_new();
string IV = KS.substr(0, 16);
int rc = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (byte*)&KS[0], (byte*)&IV[0]);
std::string rtext;
rtext.resize(ctext.size());
int out_len1 = (int)rtext.size();
rc = EVP_DecryptUpdate(ctx, (byte*)&rtext[0], &out_len1, (const byte*)&ctext[0], (int)ctext.size());
int out_len2 = (int)rtext.size() - out_len1;
rc = EVP_DecryptFinal_ex(ctx, (byte*)&rtext[0] + out_len1, &out_len2);
try
{
rtext.resize(out_len1 + out_len2);
}
catch (exception e)
{
}
return rtext;
}
Upvotes: 2
Views: 5359
Reputation: 11792
Your call to
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString.Substring(0,32));
fails because there are not 32 characters in that string. Yes, there would be 32 bytes if the string is encoded as UTF8. But Substring takes a count of characters.
Changing that line to
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString);
gives a 32-byte long key.
Since you can't count on getting proper input for the KeyString, you could validate after this point that your key length is long enough.
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString);
if (Key.Length < 32)
throw new KeyLengthException("some useful info as to why this was thrown"); // or some other appropriate Exception type you create or resuse.
If I'm correct in assuming which key, IV, and block sizes you require, this should do what you need:
public static string EncryptString(string message, string KeyString, string IVString)
{
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString).Take(32).ToArray();
if (Key.Length < 32)
throw new Exception("KeyString not at least 32 bytes.");
byte[] IV = UTF8Encoding.UTF8.GetBytes(IVString).Take(16).ToArray();
if (Key.Length < 32)
throw new Exception("IVString not at least 16 bytes.");
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.KeySize = 128;
rj.BlockSize = 128;
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
rj.Padding = PaddingMode.PKCS7;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}
Upvotes: 1