I am working on an application that utilizes a C# server and a C++ client, with licensing data being transferred between the two applications. I obviously want to encrypt these licenses for security reasons, but I am having some trouble finding a library that will fit my purposes for C++. Namely, I have tried both Crypto++ and CryptoAPI. Crypto++ seems like a nice, easy to use library, but the results of Crypto++'s encryption and C#'s encryption are different. CryptoAPI could do the job since it's maintained by Microsoft, but the API is confusing and difficult to understand. Also, strangely, C# is generating the same encrypted output with each runtime, even though I don't touch the random generation of the IV. Crypto++ doesn't do this (the output changes with each runtime under random IVs).
Does anyone have any suggestions or guidelines? I am using CBC modes for both Crypto++ and C#, so I don't think that is an issue. I'm currently using TripleDES to get the program working first. Should I use a different algorithm (I most certainly will once I'm done)?
Code, as requested (sorry about that):
public static string Encrypt(string ToEncrypt, string Key)
{
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(ToEncrypt);
TripleDESCryptoServiceProvider tDes = new TripleDESCryptoServiceProvider();
tDes.Key = keyArray;
tDes.Mode = CipherMode.CBC;
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);
}
And decryption (C++):
std::string Decrypt(std::string ToDecrypt, string Key)
{
const byte *byteKey = (byte*) Key.c_str();
CryptoPP::SecByteBlock key(CryptoPP::DES_EDE2::DEFAULT_KEYLENGTH);
key.Assign(byteKey, Key.length());
byte iv[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
try {
std::string recovered, cipher;
CryptoPP::CBC_Mode<CryptoPP::DES_EDE2>::Decryption d;
d.SetKeyWithIV(key, key.size(), iv);
CryptoPP::StringSource(ToDecrypt, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(cipher)));
CryptoPP::StringSource(cipher, true, new CryptoPP::StreamTransformationFilter(d, new CryptoPP::StringSink(recovered)));
std::cout << "Recovered: " << recovered << std::endl;
return recovered;
} catch (const CryptoPP::Exception &e) {
std::cout << e.what() << std::endl;
exit(1);
}
}
Decryptfunction does not use theKeyargument it's passed -- is this intentional?