Расшифровка зашифрованных строк RijndaelManaged с помощью CryptDecrypt

Хорошо, я пытаюсь использовать Win32 Crypto API на С++ для расшифровки строки, зашифрованной на С# (.NET 2) с помощью класса RijndaelManaged. Но мне совсем не повезло, я получаю тарабарщину или код ошибки Win32 с неверными данными. Все мои ключи, капельница и соль совпадают, я посмотрел в часах оба тестовых приложения. Я потратил все, что говорю, глядя на это, и я официально застрял.

Во всяком случае, вот С#

            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();

С++ для расшифровки:

                                    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++ работает нормально. Может ли кто-нибудь найти ошибку в моем пути. Меня это начинает угнетать :(


person Community    schedule 06.02.2009    source источник


Ответы (3)


Хорошо, моя ошибка, я не включил определение Struct для keyblob в C++, и оказалось, что вам нужен непрерывный блок данных для ключа с заголовком, но я использовал пример MSDN, в котором был указатель на данные ключа . Что неправильно!

person Community    schedule 09.02.2009

Я вижу, что вы используете режим цепочки CBC для шифрования обычного текста.

Вы уверены, что используете тот же режим цепочки для расшифровки зашифрованного текста?

(Извините. Я не могу понять это из кода)

person Niyaz    schedule 06.02.2009
comment
Согласно MSDN, по умолчанию для AES используется CBC. Хотя может и ошибся. - person ; 06.02.2009

Есть несколько вещей, которые вы должны проверить, так как часть кода (объявления и т. д.) отсутствует:

  • Размер блока - обычно он должен быть таким же, как размер ключа, я думаю, что это может быть даже значение по умолчанию, поскольку вы не указываете его на стороне C++. Установите его на 256 на стороне С#, я думаю, лучше, чтобы вы явно указали его и на С++.
  • Заполнение - управляемые классы имеют PKCS7 в качестве заполнения по умолчанию, я думаю, что это также значение по умолчанию для функций cryptoAPI, но я не уверен.
  • Я предполагаю, что GetPassPhrase, GetIV и т. д. дают вам те же ключи, которые вы используете на стороне C++?
  • Непонятно, как передаются зашифрованные данные между программами, может какая-то ошибка перевода? Например. base64, URL-кодирование и т. д.
person AviD    schedule 08.02.2009