2009-03-29 29 views
0

Crypto APIを使用してRC4暗号化キーを生成するアンマネージドアプリケーションがあります。この管理されていないアプリケーションは、このRC4キーを使用して一部のデータを暗号化します。このRC4キーを使用して情報を復号化する、クライアント側の管理されていないアプリケーションもあります。Crypto API .NET RSAの相互運用性

しかし、このクライアントアプリケーションでは、クライアント側で生成された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を使用して、プレーンテキストキーをエクスポートすることができました注意してください)

クライアント公開鍵は、

を使用して作成されます。

クライアント公開鍵は

CryptExportKey(hKeyPair, 0, PUBLICKEYBLOB, 0, lpData, &nSize); 

セッションキーが

CryptImportKey(hProv、lpData、nsizeの場合を使用してインポートされ

  1. クライアントの公開鍵を使用して、サーバー側で作成されて使用してエクスポートされます、NULL、0、&hPublicKey

  2. セッションキーはSIMPLEBLOB形式に

    CryptExportKey(HKEY、hPublicKey、SIMPLEBLOB、0、lpData、& nsizeの場合)を生成するために、クライアントの公開鍵を使ってRC4をencrytingによって生成されます。

は今私の要件は、上記の手順を持っているために管理バージョンで(ステップ1 & 2)であり、ここで私がやっているものです:

//用いて抽出したテキスト形式のキーデータを読みますコードプロジェクトの記事 バイト[] 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をdiongときのように、正しいSIMPLEBLOBセッション鍵を生成し、管理対象外の2はありませんバージョン。このコードで私は間違って何をしていますか?

答えて

1

私はここで初心者だが、私はちょうどMSDNのドキュメントで次のように読んで:

マイクロソフト暗号APIとの相互運用性(CAPI)

管理されていないCAPIでのRSAの実装とは異なり、RSACryptoServiceProviderクラスは、暗号化された後、解読される前に、暗号化されたバイト配列の順序を逆転させます。デフォルトでは、RSACryptoServiceProviderクラスで暗号化されたデータはCAPI CryptDecrypt関数で復号化できず、CAPI CryptEncryptメソッドで暗号化されたデータはRSACryptoServiceProviderクラスで復号化できません。

APIの間で相互運用する場合、あなたが逆の順序に補償されない場合は、RSACryptoServiceProviderクラスは、CryptographicExceptionがスローされます。

これが問題になりますか?