Crypto API を使用して RC4 暗号化キーを生成するアンマネージド アプリケーションがあります。このアンマネージド アプリケーションは、この RC4 キーを使用して一部のデータを暗号化します。この RC4 キーを使用して情報を復号化するクライアント側の管理されていないアプリケーションもあります。
ただし、このクライアント アプリでは、セッション キーを送信しています -> クライアント側で生成された RSA 公開キー (SIMPLEBLOB) を使用して暗号化された RC4 キー。暗号化されたセッション キーの生成は、以前はアンマネージ コードを使用して行われていましたが、部分信頼の下で Web アプリケーションからこのコードを実行する必要があるため、現在は C# に変換する必要があります。
キーは次を使用して生成されます
CryptGenKey(hProv, CALG_RC4, KEY_LENGTH | CRYPT_EXPORTABLE, &hKey);
を使用してファイルシステムにエクスポートされます
CryptExportKey(hKey, 0, OPAQUEKEYBLOB, 0, lpBuffer, &nSize);
(この記事http://www.codeproject.com/KB/security/plaintextsessionkey.aspxを使用して、プレーンテキストキーをエクスポートできたことに注意して ください)
クライアントの公開鍵は次を使用して作成されます
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKeyPair);
クライアントの公開鍵は次を使用してエクスポートされます
CryptExportKey(hKeyPair, 0, PUBLICKEYBLOB, 0, lpData, &nSize);
セッションキーは、サーバー側で作成されます
クライアントの公開鍵は次を使用してインポートされます
CryptImportKey(hProv、lpData、nSize、NULL、0、&hPublicKey
セッション キーは、クライアントの公開鍵を使用して RC4 を暗号化し、SIMPLEBLOB 形式を生成することによって生成されます。
CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, lpData, &nSize);
今、私の要件は、管理されたバージョンで上記の手順 (手順 1 と 2) を実行することです。これが私がやっていることです:
// コード プロジェクトの記事を使用して抽出されたプレーン テキストのキー データを読み取ります byte[] keyMaterial = File.ReadAllBytes(@"C:\keyMaterial.txt");
// クライアントの公開鍵をインポート
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "Container Name";
cspParams.KeyNumber = (int)KeyNumber.Exchange;
cspParams.ProviderType = 1;
cspParams.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
RSACryptoServiceProvider rsaClient = new RSACryptoServiceProvider(cspParams);
rsaClient.ImportCspBlob(File.ReadAllBytes(@"C:\client.key"));
//Generate a SIMPLEBLOB session key
byte[] session = GetRC4SessionBlobFromKey(keyMaterial, rsaClient);
//Encrypt a key using public key and write it in a SIMPLEBLOB format
public byte[] GetRC4SessionBlobFromKey(byte[] keyData, RSACryptoServiceProvider publicKey)
{
using(MemoryStream ms = new MemoryStream())
using(BinaryWriter w = new BinaryWriter(ms))
{
w.Write((byte) 0x01); // SIMPLEBLOB
w.Write((byte) 0x02); // Version 2
w.Write((byte) 0x00); // Reserved
w.Write((byte) 0x00); // Reserved
w.Write(0x00006801); // ALG_ID = RC4 for the encrypted key.
w.Write(0x0000a400); // CALG_RSA_KEYX
w.Write(publicKey.Encrypt(keyData, false));
w.Flush();
return ms.ToArray();
}
}
これにより、アンマネージド バージョンと同じサイズのデータが生成されますが、アンマネージド バージョンの手順 1 と 2 の場合のように正しい SIMPLEBLOB セッション キーが生成されません。このコードで何が間違っていますか?