2009-02-06 3 views
0

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

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

ответ

1

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

0

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

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

(. Я сожалею, что я не в состоянии понять, что из кода)

+0

Согласно MSDN, по умолчанию для AES используется CBC. Хотя это может быть неправильно. – 2009-02-06 17:29:12

0

Есть несколько вещей, которые вы должны проверить, так как некоторые из кода (деклараций и т.д.) отсутствуют:

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

 Смежные вопросы

  • Нет связанных вопросов^_^