SSL / TLSセキュアチャネルの信頼関係を確立できませんでした— SOAP


326

Visual Studioで生成されたWebサービスプロキシを介して、.NET(C#)2.0のWindowsアプリで生成された、C#(2.0)で記述されたWebサービスの簡単なWebサービスコールがあります。これは数年前から機能しており、動作している12か所ほどの場所で引き続き機能しています。

新しいサイトでの新規インストールで問題が発生しています。Webサービスを呼び出そうとすると、次のメッセージで失敗します。

SSL / TLSセキュアチャネルの信頼関係を確立できませんでした

WebサービスのURLはSSL(https://)を使用しますが、これは他の多くの場所から長い間機能してきました(そして機能し続けています)。

どこを見ますか?これは、このインストールに固有のWindowsと.NET間のセキュリティの問題ですか?もしそうなら、どこで信頼関係を設定しますか?道に迷いました!


私の場合、このエラーはIPアドレス転送が原因で発生しました。
cja 2017年

回答:


166

考え(過去の痛みに基づく):

  • サーバーへのDNSと見通し線はありますか?
  • 証明書の正しい名前を使用していますか?
  • 証明書はまだ有効ですか?
  • 正しく構成されていないロードバランサーが物事を台無しにしていますか?
  • 新しいサーバーマシンの時計は正しく設定されていますか(つまり、UTC時間は正しいです[ローカル時間は無視してください。ほとんど関係ありません])。これはWCFにとって重要なので、通常のSOAPに影響を与える可能性がありますか?
  • 証明書の信頼チェーンの問題はありますか?サーバーからSOAPサービスにアクセスすると、SSLを取得できますか?
  • 上記に関連-証明書は正しい場所にインストールされていますか?(信頼されたルート証明機関にコピーが必要になる場合があります)
  • サーバーのマシンレベルのプロキシは正しく設定されていますか?(ユーザーのプロキシとは異なります); XP / 2003のproxycfgを参照(Vistaなどについては不明)

2
1)WebサービスがWeb上にある。ブラウザで閲覧できます。2)新しいマシンはサーバーではありません-それは私のアプリを実行しているデスクトップであり、SOAPサービスを介して注文情報を収集してアップロードします3)はい、それを参照できます。4)これは私にとって新しいものです:マシンレベルのプロキシ?
Rob Schripsema 2009年

2
はい; コードはIEプロキシ設定を使用しません。別のストアを使用します...これを構成することが重要です(プロキシを使用している場合)。XPでは、最も簡単なオプションは(IIRC) "proxycfg -i"でIE設定をインポートします。
Marc Gravell

11
マルク、ありがとう。これは私に役立ち、問題は、サーバーが、まだ信頼していないサードパーティのCAによって署名された証明書を持っていることでした。解決策は、そのCAを信頼されたルートCAリストに追加することでした。
p.campbell 2009

1
この例外が発生していたコンピューターは、タイムサーバーを使用してシステム時刻を同期できませんでした。機能する前に、時刻を手動で同期する必要がありました。
Chris-Haddox Technologies、2013

4
Fiddlerを使用してサービス呼び出しをデバッグしており、証明書インターセプトモードを使用している場合に、このエラーが発生することがあります。フィドラーのオプションでインターセプトを削除するだけで良いはずです
Ruskin

363

次のスニペットは、呼び出しているサーバーのSSL証明書に問題がある場合を修正します。たとえば、自己署名されている場合や、証明書とサーバー間のホスト名が一致していない場合があります。

これは、直接制御の外にあるサーバーを呼び出している場合は危険です。接続していると思われるサーバーと通信していることを確認できなくなるためです。ただし、内部サーバーを処理していて、「正しい」証明書を取得することが実用的でない場合は、以下を使用してWebサービスに証明書の問題を無視し、勇敢な兵士を無視するように指示します。

最初の2つはラムダ式を使用し、3つ目は通常のコードを使用します。1つ目は任意の証明書を受け入れます。最後の2つは、少なくとも証明書のホスト名が期待どおりのものであることを確認してください。
...お役に立てば幸いです

//Trust all certificates
System.Net.ServicePointManager.ServerCertificateValidationCallback =
    ((sender, certificate, chain, sslPolicyErrors) => true);

// trust sender
System.Net.ServicePointManager.ServerCertificateValidationCallback
                = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));

// validate cert by calling a function
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

// callback used to validate the certificate in an SSL conversation
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
    bool result = cert.Subject.Contains("YourServerName");
    return result;
}

6
ServicePointManagerでの私の経験。変更すると、アプリドメイン全体に影響します。答えはこれがどのように適用されることができるか非常に明確に説明されていますが、私はこの点を投げたいです。
Amzath

コールバックの設定は.NET 4.5では機能しますが、.NET 4.6では機能しません
RJB

@Amzath特定のリクエストが完了した後にこれをリセットする方法について何か提案はありますか?認定されていないサーバーに対して1つの要求を行い、元の状態に戻す必要がある場合があります。
Isaac Lyman

1
@Isaac Lyman:ServicePointManager.ServerCertificateValidationCallback = null;デフォルトの動作に戻るはずです。
Mike Chamberlain

1
@MikeChamberlain提案の唯一の問題は、グローバルアプリ設定を扱っているため、同時リクエストが安全でなくなる可能性があることです。
Isaac Lyman

178

非常に単純な「すべてをキャッチする」ソリューションは次のとおりです。

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

sebastian-castaldiのソリューションはもう少し詳細です。


21
これを#If CONFIG = "Debug"ステートメントに入れるだけで、デバッグモードでのみアクティブになります。それはうまくいきます!
cjbarth 2013

1
詳細はいいかもしれませんが、すばやく、短く、簡単なコード行についても言う必要があります。このコードは短く、トリックを行います。
allen1

これは現在のアクションでのみ動作しますか(例:ASP MVCが使用されます)?それともASP.NETアプリケーションのデフォルトの動作として設定されますか?
JeeShen Lee 2016

2
これはテスト目的でのみ使用する必要があります。このソリューションは、無効な証明書や期限切れの証明書も
含めて

1
上記のコメントで説明したように、SSL接続が有効かどうかは確認されません。そのため、システムと他のシステムの間の接続が損なわれる可能性があります。これは常に、何のために必要なのかという問題です。
レミー

35

私は個人的に次のソリューションが一番好きです:

using System.Security.Cryptography.X509Certificates;
using System.Net.Security;

...次に、エラーの取得をリクエストする前に、次の操作を行います

System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

Lukeのソリューションを調べたところ、これが見つかりました


4
このアプローチのセキュリティ上の警告については、セバスチャンカスタルディの回答を参照してください。
Edward Brey 14

これを本番環境で使用する場合のセキュリティリスクは何ですか?
Amjad 2018年

@Amjadのセキュリティリスクは、SSL / TLSを使用する利点を完全に回避することです。サーバーは好みの証明書を提示でき、このコードはエラーを無視します
1800 INFORMATION

18

Windows 2003を使用している場合は、これを試すことができます。

Microsoft管理コンソールを開きます([スタート]-> [実行]-> [mmc.exe])。

[ファイル]-> [スナップインの追加と削除]を選択します。

[スタンドアロン]タブで、[追加]を選択します。

証明書スナップインを選択し、[追加]をクリックします。

ウィザードで、コンピューターアカウントを選択し、[ローカルコンピューター]を選択します。[完了]をクリックしてウィザードを終了します。

[スナップインの追加と削除]ダイアログを閉じます。

証明書(ローカルコンピューター)に移動し、インポートするストアを選択します。

証明書を発行した会社のルートCA証明書がある場合は、[信頼されたルート証明機関]を選択します。

サーバー自体の証明書がある場合は、[その他の人]を選択します

ストアを右クリックして、[すべてのタスク]-> [インポート]を選択します

ウィザードに従って、所有している証明書ファイルを提供します。

その後、単にIISを再起動し、Webサービスをもう一度呼び出してみます。

参照:http : //www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Web- Services: -Could-not-establish-trust-relationship-for-the- SSL/ TLS- ...


2
これは私に道の一部をもたらしましたが、私はそれを動作させるために信頼されたルート証明機関セクションに証明書を持っている必要がありました。あたりとしてblogs.msdn.com/b/jpsanders/archive/2009/09/16/...
ジェイコブエワルド

17

すべての人を盲目的に信頼する必要がなく、特定のホストに対してのみ信頼の例外を作成したくない場合は、次の解決策がより適切です。

public static class Ssl
{
    private static readonly string[] TrustedHosts = new[] {
      "host1.domain.com", 
      "host2.domain.com"
    };

    public static void EnableTrustedHosts()
    {
      ServicePointManager.ServerCertificateValidationCallback = 
      (sender, certificate, chain, errors) =>
      {
        if (errors == SslPolicyErrors.None)
        {
          return true;
        }

        var request = sender as HttpWebRequest;
        if (request != null)
        {
          return TrustedHosts.Contains(request.RequestUri.Host);
        }

        return false;
      };
    }
}

次に、アプリの起動時にSsl.EnableTrustedHostsを呼び出します。


@thelemはい再読私は初めて誤読したに違いないと思います
Shiv

本番環境のすべての証明書を信頼する場合のセキュリティリスクは何ですか?
Amjad 2018年

@Amjadのセキュリティリスクは、クライアントとサーバー間のすべてのユーザーが通信の途中で自分自身を挿入し、独自のSSL証明書を使用して、クライアントとサーバー間のすべてのトラフィックを読み取ることができることです。これを行うと、SSLが無効になります。
Rob Prouse

iamがWCFアドオンを使用してwsdlからクラスを生成するときに機能する必要がありますか?
カミル

7

ルークはこれについてかなり良い記事を書いた..かなり単純明快..これを試してみる

ルークのソリューション

理由(彼の記事からの引用(マイナスののろい)) "..上記のコードの問題は、証明書が有効でない場合は機能しないことです。SSL証明書が無効なWebページに投稿するのはなぜですか?理由は私は安くて、Verisignやその他の**- *の証明書をテストボックスに支払う気がなかったので、自己署名しました。リクエストを送信すると、素敵な例外がスローされました:

System.Net.WebException 基になる接続が閉じられました。リモートサーバーとの信頼関係を確立できませんでした。

私はあなたのことを知りませんが、その例外は、POSTが失敗する原因となった、コード内の愚かな間違いによって引き起こされるもののように見えました。それで私は検索を続け、あらゆる種類の奇妙なことを微調整して実行しました。*** nをググった後で初めて、無効なSSL証明書が発生した後のデフォルトの動作は、この例外をスローすることであることがわかりました。……」


1
このソリューションは、.Net 4.5では非推奨です。すべての証明書を受け入れるだけの場合は、Sebastian Castaldiまたは以下の私の回答を参照してください。
レミー

7

MicrosoftのSSL診断ツールが問題の特定に役立つ場合があります。

UPDATEリンクが修正されました。


7
今日(2012年8月)の時点で、このリンクは解除されています。
ashes999

ダウンロードディレクトリを検索しましたが、SSL診断ツールは使用できなくなりました。:(
SASS_Shooter 2012

2
リンクを修正しましょう。私が間違っている場合は、私を修正しiis.net/downloads/community/2009/09/...
Amzath

3

この問題が発生しました。私の解決策は、手動でタイムサーバーと同期してシステム時刻を更新することでした。これを行うには、次のことができます。

  • タスクバーの時計を右クリック
  • 選択する Adjust Date/Time
  • Internet Timeタブを選択します
  • クリック Change Settings
  • 選択する Update Now

私の場合、これは正しく同期されていなかったため、正しく更新される前に数回クリックする必要がありました。正しく更新されない場合は、サーバーのドロップダウンから別のタイムサーバーを使用してみてください。


聖なる牛。この正確な事柄にぶつかった。簡単な修正をありがとう!
TheGerm 2014年

3

これを試して:

System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

少なくとも4.5 .NETフレームワークを使用する必要があることに注意してください。


3

.NETInternet Explorerのアプリでも同様の問題がありました。

証明書(私の場合は、VeriSign Class 3証明書)を信頼できる編集者の証明書に追加する問題を解決しました。

Go to Internet Options-> Content -> Publishers and import it

次の場所からエクスポートすると、証明書を取得できます。

Internet Options-> Content -> Certificates -> Intermediate Certification Authorities -> VeriSign Class 3 Public Primary Certification Authority - G5

ありがとう


1

次のようなURLのWebサーバーに対してこのエラーが発生しました。

a.b.domain.com

証明書がなかったので、DNSという名前で

a_b.domain.com

これがグーグルでトップになったので、ここでこのソリューションにヒントを置くだけです。


私の場合、ウェブサイトはワイルドカードのssl証明書(* .abcd.com)で構成されていました。設定すると、ウェブサイトのバインドはxyz-abcd.comのようになり、問題が発生していました。
2016年

1

VSクライアント側でこの問題が発生し、サービス参照を正常に追加して最初の呼び出しを実行しようとすると、次の例外が発生します。「基になる接続が閉じられました:SSL / TLSセキュアチャネルの信頼関係を確立できませんでした」 (私の場合のように)IPアドレスを持つエンドポイントURLを使用していて、この例外が発生した場合は、おそらく次の手順でサービス参照を再度追加する必要があります。

  • Internet ExplorerでエンドポイントURLを開きます。
  • 証明書エラーをクリックします(アドレスバーの赤いアイコン)
  • [証明書の表示]をクリックします。
  • 発行された「名前」を取得して、IPアドレスまたは使用していた名前を置き換え、この「名前」のエラーを取得します。

再試行 :)。ありがとう


0

私の場合、IIS 7を使用してVisual Studio環境でSSLをテストしようとしていました。

これは私がそれを機能させるためにやったことです:

  • IISの右側の[バインディング...]セクションにある私のサイトの下で、ポート443に「https」バインディングを追加し、[IIS Express開発証明書]を選択する必要がありました。

  • 私のサイトの右側の[詳細設定...]セクションで、[有効なプロトコル]を「http」から「https」に変更する必要がありました。

  • 「SSL設定」アイコンの下で、クライアント証明書に「受け入れる」を選択しました。

  • 次に、アプリプールをリサイクルする必要がありました。

  • また、mmc.exeを使用してローカルホスト証明書を個人ストアにインポートする必要がありました。

私のweb.configファイルは既に正しく構成されているため、上記のすべてを整理した後、テストを続行することができました。


web.configはどのように構成されましたか?
Chazt3n 2016年

@ Chazt3nわかりませんでしたが、しばらく前ですが、これは基本的なhttpバインディングのセットアップでした。通常、svcutilを使用して、Webサービスクライアント情報の構成情報を生成します。
ポポ2016年

0

私のソリューション(VB.Net、このアプリケーションの "ステージング"(UAT)バージョンは、 "ステージング"証明書で動作する必要がありますが、ライブサイトに配置された後のリクエストには影響しません):

    ...
        Dim url As String = ConfigurationManager.AppSettings("APIURL") & "token"
        If url.ToLower().Contains("staging") Then
           System.Net.ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
        End If
    ...

    Private  Function AcceptAllCertifications(ByVal sender As Object, ByVal certification As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
        Return True
    End Function

-3

ServerCertificateValidationCallbackがtrueを返した場合、動作しない場合は不良です。 私のServerCertificateValidationCallbackコード:

ServicePointManager.ServerCertificateValidationCallback += delegate
{
    LogWriter.LogInfo("Проверка сертификата отключена, на уровне ServerCertificateValidationCallback");
    return true;
};

防止した私のコードはServerCertificateValidationCallbackを実行します:

     if (!(ServicePointManager.CertificatePolicy is CertificateValidation))
    {
        CertificateValidation certValidate = new CertificateValidation();
        certValidate.ValidatingError += new CertificateValidation.ValidateCertificateEventHandler(this.OnValidateCertificateError);
        ServicePointManager.CertificatePolicy = certValidate;
    }

OnValidateCertificateError関数:

private void OnValidateCertificateError(object sender, CertificateValidationEventArgs e)
{
    string msg = string.Format(Strings.OnValidateCertificateError, e.Request.RequestUri, e.Certificate.GetName(), e.Problem, new Win32Exception(e.Problem).Message);
    LogWriter.LogError(msg);
    //Message.ShowError(msg);
}

CertificateValidationコードを無効にし、ServerCertificateValidationCallbackを非常にうまく実行しました


証明書の検証を無効にしないでください。代わりに、検証の失敗の原因となっている問題を修正します。
Dan

これを本番環境で使用する場合のセキュリティリスクは何ですか?
Amjad 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.