RijndaelManaged の暗号化された文字列を CryptDecrypt で復号化する
-
22-08-2019 - |
質問
OK、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++ は正常に実行されています。私のやり方で間違いを見つけられる人はいますか?憂鬱になり始めています:(
解決
私のせいで[OK]を、私はC ++でkeyblobのための構造体のDEFが含まれていませんでしたし、それはあなたがヘッダを持つキーのデータのcontigousブロックを必要と判明したが、私はへのポインタを持っていたMSDNの例を使用していましたキーデータ。どちらが間違っている!
他のヒント
私はあなたがプレーンテキストを暗号化するために、CBC連鎖モードを使用していることがわかります。
あなたはCYPHERテキストを解読するために、同じ連鎖モードを使用していることを確認?です。
(私は申し訳ありません。私はコードからそれを理解することはできませんよ)
一部のコード (宣言など) が欠落しているため、確認する必要があることがいくつかあります。
- ブロック サイズ - これは通常、キー サイズと同じである必要があります。C++ 側で指定しないため、デフォルトになる可能性もあると思います。C# 側で 256 に設定します。C++ でも明示的に指定するのが最善だと思います。
- パディング - マネージド クラスにはデフォルトのパディングとして PKCS7 があります。 考える cryptoAPI 関数のデフォルトでもありますが、よくわかりません。
- GetPassPhrase、GetIV などでは、C++ 側で使用しているのと同じキーが提供されると思いますか?
- 暗号化されたデータがプログラム間でどのように受け渡されるのかは不明ですが、何らかの変換エラーがある可能性はありますか?例えば。Base64、URLエンコードなど。
所属していません StackOverflow