1. ホーム
  2. c#

[解決済み] ServerCertificateValidationCallbackの使用に関するベストプラクティス

2022-03-12 16:43:23

質問

私は、2つのバックエンドサーバー間でいくつかのHTTP通信を使用するプロジェクトに取り組んでいます。サーバーは認証にX509証明書を使用しています。言うまでもなく、サーバーA(クライアント)がサーバーB(サーバー)に接続を確立するとき、使用される証明書が信頼できるサードパーティの権威からではないので、SSL/TLS検証エラーが発生します。

通常、これを処理する方法としては ServicePointManager.ServerCertificateValidationCallback などと言う。

ServicePointManager.ServerCertificateValidationCallback += 
        (sender, cert, chain, error) =>
{
    return cert.GetCertHashString() == "xxxxxxxxxxxxxxxx";
};

この方法は、理想的でないことを除けば、うまくいきます。これは本質的に、アプリケーションによって行われるすべてのhttpリクエストの検証手順をオーバーライドするものです。そのため、他のクラスがHTTPリクエストを実行しようとすると、失敗します。また、もし他のクラスが ServicePointManager.ServerCertificateValidationCallback を使用すると、突然通信に失敗するようになります。

唯一の解決策は、別の AppDomain クライアントの HTTP リクエストを実行するためです。しかし、1つのHTTPリクエストを実行するためだけに、そのようなことをしなければならないのは、本当に馬鹿げています。オーバーヘッドがとんでもないことになります。

このことを念頭に置いて、他のウェブクライアントに影響を与えずにクライアントのSSL/TLS検証を処理しながらウェブサービスにアクセスできる、.NETのより良い実践方法があるかどうか、誰か調査したことがありますか?

どのように解決するのですか?

.NET 4.5+で動作する許容できる(安全な)方法論としては HttpWebRequest.ServerCertificateValidationCallback . このコールバックを特定のリクエストのインスタンスに割り当てると、他のリクエストに影響を与えることなく、そのリクエストの検証ロジックだけが変更されます。

var request = (HttpWebRequest)WebRequest.Create("https://...");
request.ServerCertificateValidationCallback += 
        (sender, cert, chain, error) =>
{
    return cert.GetCertHashString() == "xxxxxxxxxxxxxxxx";
};