探索のセキュリティのサンプル
Discovery 仕様では、探索プロセスに参加するエンドポイントをセキュリティで保護する必要はありません。 探索メッセージをセキュリティで強化することで、さまざまな種類の攻撃 (メッセージの改ざん、サービス拒否、リプレイ、なりすまし) が軽減されます。
DiscoveryScenario サンプルでは、コンパクトな署名形式 (WS-Discovery 仕様のセクション 8.2 を参照) を使用してメッセージ署名の計算と検証を行うカスタム チャネルの実装方法を示します。 このサンプルは、2005 Discovery 仕様と 1.1 バージョンの両方に対応しています。
カスタム チャネルは、探索エンドポイントおよびアナウンス エンドポイントの既存のチャネル スタックの上に適用されます。 これにより、署名ヘッダーがすべての送信メッセージに適用されます。 署名は受信メッセージで検証され、署名が一致しない場合やメッセージに署名がない場合、そのメッセージは破棄されます。 このサンプルでは、メッセージの署名と検証を行うために証明書を使用します。
ディスカッション
WCF は拡張性が高く、ユーザーは必要に応じてチャネルをカスタマイズできます。 このサンプルでは、セキュリティで保護されたチャネルを作成する、探索のセキュリティ保護されたバインド要素を実装します。 セキュリティで保護されたチャネルは、メッセージ署名を適用および検証します。このチャネルは現在のスタックの上に適用されます。
セキュリティ保護されたバインディング要素は、セキュリティで保護されたチャネル ファクトリとチャネル リスナーを作成します。
セキュリティで保護されたチャネル ファクトリ
セキュリティで保護されたチャネル ファクトリは、メッセージ ヘッダーにコンパクトな署名を追加する出力チャネルまたは双方向チャネルを作成します。 メッセージをできるだけ小さくするために、コンパクトな署名形式が使用されます。 コンパクトな署名の構造の例を次に示します。
<d:Security ... >
[<d:Sig Scheme="xs:anyURI"
[KeyId="xs:base64Binary"]?
Refs="..."
[PrefixList]="xs:NMTOKENS"
Sig="xs:base64Binary"
... />]?
...
</d:Security>
Note
PrefixList
は、Discovery プロトコルの 2008 バージョンで追加されました。
このサンプルでは、署名を計算するために、展開される署名のアイテムを特定します。 WS-Discovery 仕様の規定のとおり、XML 署名 (SignedInfo
) が ds
名前空間プレフィックスを使用して作成されます。 探索の本文とすべてのヘッダーおよびアドレス名前空間は署名で参照されるため、改ざんされることはありません。 参照される各要素が排他的正規化 (http://www.w3.org/2001/10/xml-exc-c14n#) を使用して変換された後、SHA-1 ダイジェスト値が計算されます (http://www.w3.org/2000/09/xmldsig#sha1)。 参照されるすべての要素とそのダイジェストの値に基づいて、RSA アルゴリズム (http://www.w3.org/2000/09/xmldsig#rsa-sha1) を使用して署名の値が計算されます。
メッセージは、クライアントが指定した証明書を使用して署名されます。 バインディング要素の作成時に、ストアの場所、名前、証明書のサブジェクト名を指定する必要があります。 コンパクトな署名の KeyId
は、署名トークンのキー識別子を表します。これは、署名トークンのサブジェクト キー識別子 (SKI) か、署名トークンの公開キーの SHA-1 ハッシュ (SKI が存在しない場合) です。
セキュリティで保護されたチャネル リスナー
セキュリティで保護されたチャネル リスナーは、受信メッセージのコンパクトな署名を検証する入力チャネルまたは双方向チャネルを作成します。 署名を検証するために、メッセージに結び付けられているコンパクトな署名で指定された KeyId
を使用して、指定されたストアから証明書が選択されます。 メッセージに署名がない場合や署名のチェックに失敗した場合、そのメッセージは破棄されます。 このサンプルでは、セキュリティで保護されたバインディングを使用するために、探索のセキュリティ保護されたバインド要素が追加されたカスタムの UdpDiscoveryEndpoint と UdpAnnouncementEndpoint を作成するファクトリを定義します。 これらのセキュリティで保護されたエンドポイントは、探索アナウンス リスナーや探索サービスで使用できます。
サンプルの詳細
このサンプルには、1 つのライブラリと 4 つのコンソール アプリケーションが含まれています。
DiscoverySecurityChannels: セキュリティで保護されたバインディングを公開するライブラリ。 このライブラリは、送信/受信メッセージのコンパクトな署名の計算と検証を行います。
Service: ICalculatorService コントラクトを公開するサービス (自己ホスト型)。 このサービスは、Discoverable としてマークされます。 メッセージの署名に使用する証明書の詳細はユーザーが指定します。ストアの場所と名前、証明書のサブジェクト名またはその他の一意の識別子、およびクライアント証明書 (受信メッセージの署名のチェックに使用する証明書) の保存場所を指定します。 これらの詳細に基づいて、セキュリティが追加された UdpDiscoveryEndpoint が作成されて使用されます。
Client: このクラスでは、ICalculatorService の探索と、サービスに対するメソッドの呼び出しを試行します。 ここでも、メッセージの署名と検証を行うために、セキュリティが追加された UdpDiscoveryEndpoint が作成されて使用されます。
AnnouncementListener: オンラインおよびオフラインのアナウンスをリッスンし、セキュリティで保護されたアナウンス エンドポイントを使用する自己ホスト型のサービス。
Note
Setup.bat を複数回実行すると、証明書が重複し、証明書マネージャーから、追加する証明書を選択するように求められます。 その場合は、既に重複が作成されているため、Setup.bat を中止して Cleanup.bat を呼び出します。 Cleanup.bat でも、削除する証明書を選択するように求められます。 一覧から証明書を選択し、残っている証明書がなくなるまで Cleanup.bat を実行します。
このサンプルを使用するには
Visual Studio の開発者コマンド プロンプトから Setup.bat スクリプトを実行します。 このサンプルでは、証明書を使用してメッセージの署名と検証を行います。 スクリプトによって、証明書が Makecert.exe を使用して作成され、Certmgr.exe を使用してインストールされます。 このスクリプトは、管理者権限で実行する必要があります。
サンプルをビルドして実行するには、Visual Studio で Security.sln ファイルを開き、 [すべてリビルド] を選択します。 複数のプロジェクトを起動するようにソリューションのプロパティを更新します。ここでは、DiscoverySecureChannels を除くすべてのプロジェクトで [開始] を選択します。 通常どおりソリューションを実行します。
サンプルの作業が終了したら、このサンプルで作成した証明書を削除する Cleanup.bat スクリプトを実行します。