Расшифровка управляемых Rijndael зашифрованных строк с помощью CryptDecrypt
-
22-08-2019 - |
Вопрос
Хорошо, я пытаюсь использовать Win32 Crypto API на C ++ для расшифровки строки, зашифрованной на C # (.NET 2) с помощью класса RijndaelManaged.Но мне совсем не везет, я получаю бред или неверный код ошибки Data Win32.Все мои ключи, IV и salt совпадают, я просмотрел в watch оба тестовых приложения.Я потратил все время, чтобы посмотреть на это, и я официально застрял.
В любом случае, вот C#
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(GetPassPhrase(), salt, 1000);
RijndaelManaged rijndael = new RijndaelManaged();
rijndael.BlockSize = 128;
rijndael.KeySize = 256;
rijndael.Mode = CipherMode.CBC;
rijndael.Key = pdb.GetBytes(m_KeySize);
rijndael.IV = GetIV(iv);
ICryptoTransform encryptor = rijndael.CreateEncryptor();
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
Byte[] encryptedBytes = null;
Byte[] toBeEncrypted = UnicodeEncoding.Unicode.GetBytes(value);
csEncrypt.Write(toBeEncrypted, 0, toBeEncrypted.Length);
csEncrypt.FlushFinalBlock();
encryptedBytes = msEncrypt.ToArray();
C ++ для расшифровки это:
keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_AES_256;
keyBlob.cbKeySize = KEY_SIZE;
keyBlob.rgbKeyData = &byKey[0];
if ( CryptImportKey( hProv, (const LPBYTE) &keyBlob, sizeof(BLOBHEADER) + sizeof(DWORD) + KEY_SIZE, 0, CRYPT_EXPORTABLE, &hKey ) )
{
if ( CryptSetKeyParam( hKey, KP_IV, (const BYTE *) &byIV, 0))
{
DWORD dwLen = iDestLen;
if ( CryptDecrypt( hKey, 0, TRUE, 0, pbyData, &dwLen))
{
if ( dwLen < (DWORD) *plOutSize)
{
memcpy_s(pbyOutput, *plOutSize, pbyData, dwLen);
*plOutSize = dwLen;
bRet = TRUE;
}
}
else
{
// Log
DWORD dwErr = ::GetLastError();
int y =0;
}
}
}
Я успешно вызываю CryptAcquireContext, и мой C ++ выполняется нормально.Кто-нибудь может заметить ошибку в моих способах.Это начинает меня угнетать , знаете:(
Решение
Хорошо, моя ошибка, я не включил Struct def для keyblob в C ++, и оказывается, что вам нужен непрерывный блок данных для ключа с заголовком, но я использовал пример MSDN, в котором был указатель на ключевые данные.Что неправильно!
Другие советы
Я вижу, что вы используете режим цепочки CBC для шифрования обычного текста.
Вы уверены, что используете тот же режим цепочки для расшифровки зашифрованного текста?
(Мне очень жаль.Я не в состоянии понять это из кода)
Есть несколько вещей, которые вы должны проверить, поскольку некоторые части кода (объявления и т.д.) Отсутствуют:
- Размер блока - обычно он должен совпадать с размером ключа, я думаю, это может быть даже значение по умолчанию, поскольку вы не указываете его на стороне C ++.Установите для него значение 256 на стороне C #, я думаю, будет лучше, если вы явно укажете его и на C ++.
- Заполнение - управляемые классы имеют PKCS7 в качестве заполнения по умолчанию, я подумай это также используется по умолчанию для функций CryptoAPI, но я не уверен.
- Я предполагаю, что GetPassPhrase, GetIV и т.д. Дают вам те же ключи, которые вы используете на стороне C ++?
- Неясно, как зашифрованные данные передаются между программами, возможно ли, что произошла какая-то ошибка перевода?Например.base64, кодирование URL-адреса и т.д.