.NET TIPS

SSL通信で信頼されない証明書を回避するには?[C#、VB、2.0、3.0、3.5]

デジタルアドバンテージ 一色 政彦
2009/04/23

 .NETでは、WebClientクラス(System.Net名前空間)やWebRequestクラス(System.Net名前空間)でWeb上のリソースにアクセスでき(参考「TIPS:WebClientクラスでWebページを取得するには?」「TIPS:WebRequest/WebResponseクラスでWebページを取得するには?」)、これらのクラスはSSL(Secure Sockets Layer)でセキュリティ保護されたサイトへのアクセスもサポートしている。

 しかし、そのSSLで使用されているデジタル証明書(以降、SSL証明書)が、信頼されないもの、例えば(VeriSignなどの第三者機関が発行したデジタル証明書ではなく)makecert.exeなどにより作成した自己証明書などである場合には、サイトのアクセス時に次のようなエラー(例外)が発生する。

SSL証明書が問題でエラーが発生した例
WebException.Messageプロパティの内容は「基礎になる接続が閉じられました: SSL/TLS のセキュリティで保護されているチャネルに対する信頼関係を確立できませんでした」となっている(上図)。
また、WebException.InnerException.Messageプロパティの内容は「検証プロシージャによると、リモート証明書は無効です。」となっている(下図)。
例外は「System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)」で発生している。

 本稿では、SSL証明書を変えずに、このエラーに対処する方法(エラーを回避してサイトにアクセスする方法)を紹介する。

信頼されないSSL証明書を回避する方法

 このエラーに対処するには、SSL証明書の妥当性が検証される際に、「問題なし」と.NET Frameworkに認識させればよい。

 これには、WebサーバのSSL証明書を検証する際に呼び出されるコールバック・メソッドを設定する機能を活用すればよい。これは.NET Framework 2.0で追加された機能で、独自のSSL証明書検証手順を組み込むためのものだ。

 このコールバック・メソッドは、次の静的プロパティで設定する(ServicePointManagerはSystem.Net名前空間のクラス)。

  • ServicePointManager.ServerCertificateValidationCallbackプロパティ

 このプロパティに指定できるのは、RemoteCertificateValidationCallbackデリゲート型(System.Net.Security名前空間のクラス)のメソッドである。その型のメソッド・シグネチャは次のようになっている。

public delegate bool RemoteCertificateValidationCallback(
  Object sender,
  X509Certificate certificate,
  X509Chain chain,
  SslPolicyErrors sslPolicyErrors
)
Public Delegate Function RemoteCertificateValidationCallback( _
  sender As Object, _
  certificate As X509Certificate, _
  chain As X509Chain, _
  sslPolicyErrors As SslPolicyErrors _
) As Boolean
RemoteCertificateValidationCallbackデリゲート型のメソッド・シグネチャ
各パラメータの意味は以下のとおり。戻り値の意味は後述。
senderパラメータは、SSL通信を行っているオブジェクト(WebClientオブジェクトやWebRequestオブジェクト)。
certificateパラメータは、SSL証明書を示すオブジェクト。
chainパラメータは、証明機関のチェーンを示すオブジェクト。
sslPolicyErrorsパラメータは、SSL証明書に関連付けられたエラーを示すオブジェクト。

 この戻り値がtrueの場合は、.NET Frameworkに対して「SSL証明書の使用は問題なし」を示し、falseの場合は「SSL証明書の使用は不可」を示す(各パラメータについては上記の説明欄を参照)。

 従って、信頼されないSSL証明書であっても、戻り値としてtrueを返すようなコールバック・メソッドを作成すればよいというわけだ。具体的には次のようなコールバック・メソッドを実装すればよい。

// 信頼できないSSL証明書を「問題なし」にするメソッド
private bool OnRemoteCertificateValidationCallback(
  Object sender,
  X509Certificate certificate,
  X509Chain chain,
  SslPolicyErrors sslPolicyErrors)
{
  return true;  // 「SSL証明書の使用は問題なし」と示す
}
' 信頼できないSSL証明書を「問題なし」にするメソッド
Private Function OnRemoteCertificateValidationCallback( _
  ByVal sender As Object, _
  ByVal certificate As X509Certificate, _
  ByVal chain As X509Chain, _
  ByVal sslPolicyErrors As SslPolicyErrors _
) As Boolean

  Return True  ' 「SSL証明書の使用は問題なし」と示す

End Function
RemoteCertificateValidationCallbackデリゲートの実装例
X509CertificateクラスやX509ChainクラスはSystem.Security.Cryptography.X509Certificates名前空間のクラス。

 あとは、次のコードのように、これを先ほどのServicePointManager.ServerCertificateValidationCallbackプロパティに設定するだけだ。

ServicePointManager.ServerCertificateValidationCallback =
  new RemoteCertificateValidationCallback(
    OnRemoteCertificateValidationCallback);
ServicePointManager.ServerCertificateValidationCallback = _
  New RemoteCertificateValidationCallback( _
    AddressOf OnRemoteCertificateValidationCallback)
ServicePointManager.ServerCertificateValidationCallbackプロパティの設定

 以上で対応は完了。SSL通信を行ってもエラーが発生しないはずだ。

 なお、この方法ではすべてのSSL証明書を「SSL証明書の使用は問題なし」にしてしまうが、コールバック・メソッドのcertificateパラメータのX509Certificateオブジェクト(System.Security.Cryptography.X509Certificates名前空間)のSubjectプロパティでSSL証明書の識別名を文字列で受け取れるので、SSL証明書ごとに対応を変えるには、これを解析するなどすればよい。End of Article

利用可能バージョン:.NET Framework 2.0以降
カテゴリ:クラス・ライブラリ 処理対象:ネットワーク
使用ライブラリ:WebClientクラス(System.Net名前空間)
使用ライブラリ:WebRequestクラス(System.Net名前空間)
使用ライブラリ:ServicePointManagerクラス(System.Net名前空間)
使用ライブラリ:RemoteCertificateValidationCallbackデリゲート(System.Net.Security名前空間)
使用ライブラリ:X509Certificateクラス(System.Security.Cryptography.X509Certificates名前空間)
関連TIPS:WebClientクラスでWebページを取得するには?
関連TIPS:WebRequest/WebResponseクラスでWebページを取得するには?

この記事と関連性の高い別の.NET TIPS
プログラムでデジタル証明書をインストールするには?
ClickOnceのデジタル証明書を更新するには?
[Azure]Windows AzureアプリケーションをVisual Studioからデプロイするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」

@IT Special

- PR -

TechTargetジャパン

Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

イベントカレンダー

PickUpイベント

- PR -

アクセスランキング

もっと見る

ホワイトペーパーTechTargetジャパン

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH