I have some code for encryption in C# that I have to rewrite in C++
I saw several similar questions here on SO but somehow I still could not figure this out.
Encoding the same string with the same password yields different results.
The C# code
byte[] TestEncrypt(string data)
{
byte[] plainText = System.Text.Encoding.ASCII.GetBytes(data);
TripleDES des3 = new System.Security.Cryptography.TripleDESCryptoServiceProvider();
des3.Mode = CipherMode.CBC;
des3.Key = System.Text.Encoding.ASCII.GetBytes("12656b2e4ba2f22e");
des3.IV = System.Text.Encoding.ASCII.GetBytes("d566gdbc");
ICryptoTransform transform = des3.CreateEncryptor();
MemoryStream memStreamEncryptedData = new MemoryStream();
CryptoStream encStream = new CryptoStream(memStreamEncryptedData,
transform, CryptoStreamMode.Write);
encStream.Write(plainText, 0, plainText.Length);
encStream.FlushFinalBlock();
encStream.Close();
byte[] cipherText = memStreamEncryptedData.ToArray();
return cipherText;
}
Result 255,142,22,151,93,255,156,10,174,10,250,92,144,0,60,142
EDITED: Added new C++ version
string Test3DES()
{
string key = "12656b2e4ba2f22e";
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hCryptKey = NULL;
char pIV[] = "d566gdbc"; //simple test IV for 3DES
CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);
PlainTextKeyBlob keyBlob ={0};
keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_3DES_112;
keyBlob.cbKeySize = key.size();
memcpy(keyBlob.key, key.c_str(), key.size());
DWORD dwSizeBlob = sizeof(BLOBHEADER)+sizeof(DWORD)+key.size();
ret = CryptImportKey( hCryptProv, (const BYTE*)&keyBlob, dwSizeBlob, 0, CRYPT_EXPORTABLE, &hCryptKey );
DWORD dwMode = CRYPT_MODE_CBC;
CryptSetKeyParam(hCryptKey, KP_MODE, (BYTE*)&dwMode, 0);
CryptSetKeyParam(hCryptKey, KP_IV,(const BYTE*) pIV, 0) ;
DWORD dwFilled = 0;
BOOL ret = CryptEncrypt( hCryptKey, NULL, TRUE, 0, (LPBYTE)cipherText.c_str(), &dwFilled, (DWORD)str.size());
cipherText.resize(dwFilled);
if( hCryptKey ) CryptDestroyKey( hCryptKey );
if( hHash ) CryptDestroyHash( hHash );
if( hCryptProv ) CryptReleaseContext( hCryptProv, 0 );
return cipherText;
}
result 167,177,201,56,123,240,169,174
Old C++ version
C++
string Test3DES()
{
string key = "12656b2e4ba2f22e";
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hCryptKey = NULL;
char pIV[] = "d566gdbc"; //simple test IV for 3DES
CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptCreateHash( hCryptProv, CALG_MD5, NULL, 0, &hHash );
CryptHashData( hHash, (LPBYTE)key.c_str(), (DWORD)key.size(), 0 );
DWORD dwMode = CRYPT_MODE_CBC;
CryptDeriveKey(hCryptProv, CALG_3DES, hHash, 0, &hCryptKey);
CryptSetKeyParam(hCryptKey, KP_MODE, (BYTE*)&dwMode, 0);
CryptSetKeyParam(hCryptKey, KP_IV,(const BYTE*) pIV, 0) ;
DWORD dwFilled = 0;
BOOL ret = CryptEncrypt( hCryptKey, NULL, TRUE, 0, (LPBYTE)cipherText.c_str(), &dwFilled, (DWORD)str.size());
cipherText.resize(dwFilled);
if( hCryptKey ) CryptDestroyKey( hCryptKey );
if( hHash ) CryptDestroyHash( hHash );
if( hCryptProv ) CryptReleaseContext( hCryptProv, 0 );
return cipherText;
}
I set up some sample projects starting with your code. You didn’t include everything so I had to add some stuff. By the time I compiled and tested I was getting the same answer in both C++ and C#. I suspect the problem may be something in the way you are specifying the cipherText buffer? This is all of my test code so it should be easy for you to set up some sample project and see if you get the same result too, then maybe you can figure it out from there:
C#
C++