0

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

セッションキーは、サーバー側で作成されます

  1. クライアントの公開鍵は次を使用してインポートされます

    CryptImportKey(hProv、lpData、nSize、NULL、0、&hPublicKey

  2. セッション キーは、クライアントの公開鍵を使用して 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 セッション キーが生成されません。このコードで何が間違っていますか?

4

1 に答える 1

2

私はここでは初心者ですが、MSDNのドキュメントで次のことを読んだだけです:

Microsoft Cryptographic API (CAPI) との相互運用

アンマネージ CAPI の RSA 実装とは異なり、RSACryptoServiceProvider クラスは、暗号化後と復号化前に、暗号化されたバイト配列の順序を逆にします。デフォルトでは、RSACryptoServiceProvider クラスによって暗号化されたデータは CAPI CryptDecrypt 関数によって暗号化解除できず、CAPI CryptEncrypt メソッドによって暗号化されたデータは RSACryptoServiceProvider クラスによって暗号化解除できません。

API 間の相互運用時に逆順を補正しない場合、RSACryptoServiceProvider クラスは CryptographicException をスローします。

これが問題でしょうか?

于 2010-12-08T14:07:13.263 に答える