28

WCF の設定の泥沼を処理しようとすると、次の問題が発生します...

NetTcp バインディングを使用して WCF クライアント サーバー サービスを作成しました。セキュリティ設定に変更を加えていないため、1 台のマシンで実行すると非常にうまく機能します。しかし、別のマシンからクライアントを実行すると、送信されたセキュリティ資格情報がサーバーに不適切であると報告されました。

NetTCPはデフォルトで「保護」されており、クライアントが間違ったセキュリティの詳細、つまり、Windows のユーザー名とパスワード (または何らかの形式のドメイン認証) をサーバー上で実行していないため、サーバーに渡していたことがわかります。好まなかったであろう同じドメイン。

しかし、私が理解していないのは次のとおりです。

バインディングでセキュリティを指定していません。標準設定では、Windows ユーザー名またはパスワードが送信されることを想定していますか?

サーバーに証明書がインストールされていません-NetTCPバインディングには資格情報を保護するために何らかの形式の公開秘密鍵が必要であることを理解しています-それでも、クライアントとサーバーの両方が同じマシン上にある場合、これは機能するように見えました-データはどのように取得されましたか暗号化?それとも、同じマシン上にあり、暗号化が不要であることを WCF が認識していたので、それを望んでいますか?

クライアントとサーバーのセキュリティモードを「なし」に設定する必要がありましたが、うまく接続されています。しかし、証明書なしでデータを暗号化する方法はありますか?

最後に...トランスポートとメッセージのセキュリティの違いは何ですか?

私の理解を確認するために (シナリオを許してください!) メッセージのセキュリティは、A さんから B さんに手紙を送り、手書きをエンコードして、誰かがそれを傍受した場合に読めないようにするようなものですか? 輸送セキュリティとは、手紙を武装輸送で送ることに決めた場合に、途中でだれも手に入れることができないようにすることですか?

証明書なしで WCF で任意の形式の暗号化を行うことは可能ですか? 私のプロジェクトはプライベート プロジェクトであり、証明書を購入したくありません。とにかく、データはそれほど機密ではないので、それは私自身の知識のためです。

4

1 に答える 1

33

NetTcpBindingのデフォルトのクライアントクレデンシャルタイプはWindows認証です。Windows認証が機能するには、クライアントとサーバーの両方が同じドメイン内にあるか、相互に信頼しているドメイン(この場合はドメインを持っていない)である必要があります。

クライアントとサーバーの両方が同じドメイン上にある場合、WCFは「舞台裏」でWindows認証のメカニズムを処理します。また、クライアントとサーバーの両方が同じマシン上にある場合、それらは事実上同じドメイン内にあるため、Windowsは独自のメカニズムを使用して暗号化と復号化を処理できます。ただし、これは相互に信頼するドメイン内でのみ実行されます。

クライアントドメインとサーバードメインを相互に信頼していない場合、クライアントとサーバーは、キーを使用して相互に信頼しているかどうかを判断するための別の方法が必要です。そこで証明書が登場します。クライアントとサーバーには独自の証明書があります(またはサーバーがクライアントに証明書を発行できます)。

トランスポートセキュリティは、エンベロープの内側だけでなく外側も暗号化するようなものです。欠点は、自分の組織外の誰かに封筒を渡す必要がある場合、封筒の行き先を知るためだけに復号化キーが必要になることです。これで、封筒内のメッセージも読むことができます。一方、トランスポートのセキュリティは高速です。エンベロープとともに渡されるセキュリティオーバーヘッドデータが少なくて済みます。

メッセージセキュリティはメッセージを暗号化しますが、封筒は郵便局員(インターネットとそのルーター)が読み取ることができます。送信元と宛先のみがメッセージを復号化するためのキーを持っていますが、仲介者はメッセージを適切にルーティングできます。

要約すると、NetTcpBindingで暗号化を使用するには、クライアントとサーバーの両方がドメイン内(または相互に信頼するドメイン)にあるか、キー交換証明書を持っている必要があります。


編集:いくつかのサンプルコードを求められました-これがXAMLのバインディング要素です。通常、netTcpBinding要素内に配置されます。

<binding name="Secure" listenBacklog="4000" receiveTimeout="00:20:00" sendTimeout="00:20:01" 
   maxReceivedMessageSize="2147483647" maxConnections="200" portSharingEnabled="true">
   <!-- ~2 GB -->
   <readerQuotas maxStringContentLength="2147483647"/>
   <!-- ~2 GB max string content length -->
   <security mode="Message">
      <transport clientCredentialType="None" protectionLevel="EncryptAndSign"/>
      <message clientCredentialType="None"/>
   </security>
</binding>

重要な部分はセキュリティ要素です。トランスポートセキュリティの場合、mode属性を「Transport」に変更します。おそらく、clientCredentialTypeは「None」ではなく、コンテキストに応じて「Certificate」、「Ntlm」、または「Windows」になります。

于 2010-07-30T20:31:05.990 に答える