Я пытаюсь расшифровать часть файла с помощью wincrypt, и я не могу заставить эту функцию дешифровать правильно. Байты зашифрованы с помощью реализации RC2 в C #, и я предоставляю один и тот же пароль и IV для процесса шифрования и дешифрования (зашифровано в C #, расшифровано в c ++).
Все мои функции по пути возвращают true до финальной функции CryptDecrypt. Вместо того, чтобы я печатал больше, вот функция:
static char* DecryptMyFile(char *input, char *password, int size)
{
HCRYPTPROV provider = NULL;
if(CryptAcquireContext(&provider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{printf("Context acquired.");}
else
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if(CryptAcquireContext(&provider, 0, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
{printf("new key made.");}
else
{
printf("Could not acquire context.");
}
}
else
{printf("Could not acquire context.");}
}
HCRYPTKEY key = NULL;
HCRYPTHASH hash = NULL;
if(CryptCreateHash(provider, CALG_MD5, 0, 0, &hash))
{printf("empty hash created.");}
else
{printf("could not create hash.");}
if(CryptHashData(hash, (BYTE *)password, strlen(password), 0))
{printf("data buffer is added to hash.");}
else
{printf("error. could not add data buffer to hash.");}
if(CryptDeriveKey(provider, CALG_RC2, hash, 0, &key))
{printf("key derived.");}
else
{printf("Could not derive key.");}
DWORD dwKeyLength = 128;
if(CryptSetKeyParam(key, KP_EFFECTIVE_KEYLEN, reinterpret_cast<BYTE*>(&dwKeyLength), 0))
{printf("success");}
else
{printf("failed.");}
BYTE IV[8] = {0,0,0,0,0,0,0,0};
if(CryptSetKeyParam(key, KP_IV, IV, 0))
{printf("worked");}
else
{printf("faileD");}
DWORD dwCount = size;
BYTE *decrypted = new BYTE[dwCount + 1];
memcpy(decrypted, input, dwCount);
decrypted[dwCount] = 0;
if(CryptDecrypt(key,0, true, 0, decrypted, &dwCount))
{printf("succeeded");}
else
{printf("failed");}
return (char *)decrypted;
}
Ввод - это данные, переданные функции, зашифрованные. пароль - это тот же пароль, который используется для шифрования данных в C #. Размер - это размер данных в зашифрованном виде.
Все вышеперечисленные функции возвращают true до CryptDecrypt, что я не могу понять, почему. В то же время я не уверен, как функция CryptDecrypt могла бы редактировать мою «расшифрованную» переменную, поскольку я не передаю ссылку на нее.
Любая помощь или совет, почему это не работает, будет принята с благодарностью. Это мой первый опыт работы с wincrypt и впервые за много лет с использованием C ++.
Если это также поможет, это мое шифрование (в C #):
public static byte[] EncryptString(byte[] input, string password)
{
PasswordDeriveBytes pderiver = new PasswordDeriveBytes(password, null);
byte[] ivZeros = new byte[8];
byte[] pbeKey = pderiver.CryptDeriveKey("RC2", "MD5", 128, ivZeros);
RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();
//using an empty initialization vector for convenience.
byte[] IV = new byte[8];
ICryptoTransform encryptor = RC2.CreateEncryptor(pbeKey, IV);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
csEncrypt.Write(input, 0, input.Length);
csEncrypt.FlushFinalBlock();
return msEncrypt.ToArray();
}
Я подтвердил, что мое хеш-значение в C ++ идентично моему ключу в C #, созданному PasswordDeriveBytes.CryptDeriveKey