0

わかりました、C++ で Win32 Crypto API を使用して、C# (.NET 2) で暗号化された文字列を RijndaelManaged クラスで復号化しようとしています。しかし、私はまったく運が悪く、ジバーまたは悪いデータのWin32エラーコードが表示されます。すべてのキー、IV とソルトが一致し、時計で両方のテスト アプリを調べました。私はそれを見てすべてのことを言いましたが、公式に立ち往生しています。

とにかくここに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++ は正常に実行されています。誰でも私のやり方でエラーを見つけることができますか? それは私を知って憂鬱になり始めています:(

4

3 に答える 3

1

私のせいで、C++ にキーブロブの Struct def を含めていませんでした。ヘッダーを含むキーの連続したデータ ブロックが必要であることがわかりましたが、キー データへのポインターを持つ MSDN の例を使用していました。 . どちらが間違っています!

于 2009-02-09T17:32:28.047 に答える
0

一部のコード(宣言など)が欠落しているため、確認する必要のあることがいくつかあります。

  • ブロックサイズ-これは通常、キーサイズと同じである必要があります。これは、C ++側で指定しないため、デフォルトである可能性もあると思います。C#側で256に設定します。C++でも明示的に指定するのが最善だと思います。
  • パディング-マネージドクラスにはデフォルトのパディングとしてPKCS7があり、cryptoAPI関数のデフォルトでもあると思いますが、よくわかりません。
  • GetPassPhrase、GetIVなどは、C ++側で使用しているのと同じキーを提供すると思いますか?
  • 暗号化されたデータがプログラム間でどのように渡されるかは明確ではありませんが、何らかの変換エラーが発生する可能性はありますか?例:base64、URLエンコードなど。
于 2009-02-08T01:47:10.407 に答える
0

プレーン テキストの暗号化に CBC チェーン モードを使用しているようです。

同じ連鎖モードを使用して暗号文を復号化していますか?

(すみません。コードからは理解できません)

于 2009-02-06T17:24:54.133 に答える