У меня есть код для шифрования на C#, который я должен переписать на C++ Я видел несколько подобных вопросов здесь, на SO, но почему-то я все еще не мог понять это. Кодирование одной и той же строки с тем же паролем дает разные результаты..NET triple des to Windows API
C# код
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;
}
Результат 255,142,22,151,93,255,156,10,174,10,250,92,144,0,60,142 Редакцией: версия Добавлен новый 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);
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;
}
результат 167,177,201,56,123,240,169,174
Старая версия на С ++
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;
}
В чем ваш вопрос/проблема? – Mat
Ваш ключ слишком короткий (120 бит), минимум 128 бит. [MSDN] (http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledes.key.aspx): этот алгоритм поддерживает длину ключа от 128 бит до 192 бит с шагом 64 бит –
Он отлично работает в C# – SparcU