1

C#/WCF を使用しています。クライアントによって呼び出される Web サービスがあります。これはサービス定義です:

<service behaviorConfiguration="WCFInterface.CommonBehavior" name="WCFInterface.Content">
  <endpoint address="" binding="ws2007HttpBinding" bindingConfiguration="wsHttpUserName"
 contract="ABB.fTunes.WCFInterface.IContent">
    <identity>
      <dns value="fTunesTestServer" />
    </identity>
  </endpoint>
  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

そして、これはバインディングです:

<ws2007HttpBinding>
  <binding name="wsHttpUserName">
    <security mode="Message">
      <message clientCredentialType="UserName"/>
    </security>
  </binding>
</ws2007HttpBinding>

これを正しく理解していれば、サーバーからクライアントに送信されるメッセージは証明書で暗号化されています。現在、私はまだ開発者証明書を扱っています。サーバー上にルート証明書、証明書失効リスト、およびキーを作成しました。

Windows インストーラーを使用してクライアントをインストールしており、証明書をインストールするためのカスタム インストール アクションがあります。

次のコードは、証明書がストアに追加される方法を示しています。

Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClientCertificates.MyRoot.cer");
byte[] buffer = new byte[((int)(manifestResourceStream.Length - 1L)) + 1];
manifestResourceStream.Read(buffer, 0, (int)manifestResourceStream.Length);
manifestResourceStream.Close();

var cert = new X509Certificate2(buffer);
var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();

/*
// The CRL is also needed, no idea why
manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClientCertificates.MyRoot.crl");
buffer = new byte[((int)(manifestResourceStream.Length - 1L)) + 1];
manifestResourceStream.Read(buffer, 0, (int)manifestResourceStream.Length);
manifestResourceStream.Close();
cert = new X509Certificate2(buffer);
store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
*/

// This is the key 
manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ClientCertificates.MyTestServer.cer");
buffer = new byte[((int)(manifestResourceStream.Length - 1L)) + 1];
manifestResourceStream.Read(buffer, 0, (int)manifestResourceStream.Length);
manifestResourceStream.Close();

cert = new X509Certificate2(buffer);
store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();

証明書のインストールは機能しますが、Web サービスを呼び出すとSecurityNegotiationException. 証明書失効リストを手動で追加すると、サーバーとの通信が機能します。プログラムで実行しようとすると (上記のコードを参照)、機能しません。「要求されたオブジェクトが見つかりませんでした」という例外が発生します。

いろいろな店を利用しようとしましたが、うまくいきませんでした。

2 つの質問があります。a) なぜクライアントで CRL が必要なのですか? b) 必要な場合、どのようにプログラムでインストールできますか? 上記の私の間違いはどこですか?

助けてくれてありがとう、ケイ

4

3 に答える 3

4

通常、CRLはオンラインで利用可能であり、サーバー証明書で指定された失効URLからダウンロード可能である必要があります。それを取得するための帯域外メカニズムがあるかどうかはわかりませんが、あったとしても、目的をやや損なうことになります(サーバー証明書が侵害/取り消されたことをクライアントが発見できるようにします)。とは言うものの、CRLは、実際の相互認証に証明書を使用していて、キーが危険にさらされていることを心配していない限り、自己署名証明書には本当にやり過ぎです(この場合、商用証明書を購入して処理させます) 。

失効URLなしで証明書を生成できない場合は、本当に必要でない限り、CRLのクライアントチェックを完全に無効にすることをお勧めします。これを行うには、Webサービスクライアントのapp.configに以下を追加します。

  <system.net>
    <settings>
      <servicePointManager checkCertificateRevocationList="false"/>
    </settings>
  </system.net>

WCFを使用している場合は、代わりにserviceCertificate-> revocationMode:NoCheckの下でclientCredentialsendpointBehaviorに接続する必要がある場合があります。

于 2009-09-26T08:16:31.173 に答える