C#(2.0)で記述されたWebサービスのために、Visual Studioによって生成されたWebサービスプロキシを介して、.NET(C#)2.0 Windowsアプリケーションによって生成された単純なWebサービス呼び出しがあります。これは数年間有効であり、それが実行されている数十か所ほどの場所でそうし続けています。
新しいサイトでの新しいインストールで問題が発生しています。 Webサービスを呼び出そうとすると、次のメッセージが表示されて失敗します。
SSL/TLSセキュアチャネルの信頼関係を確立できませんでした
WebサービスのURLはSSL(https://)を使用します - しかし、これは他の多くの場所から長い間(そしてそうし続けています)働いています。
どこに見えますか?これは、このインストールに特有のWindowsと.NETの間のセキュリティ問題でしょうか。もしそうなら、どこで信頼関係を設定しますか?道に迷いました!
考え(過去の痛みに基づく):
次のスニペットは、呼び出しているサーバーのSSL証明書に問題がある場合を修正します。たとえば、自己署名されているか、証明書とサーバーの間のホスト名が一致していない可能性があります。
これは危険です 直接制御できないサーバーに電話をかけている場合は、接続していると思うサーバーと会話していることを確認できなくなります。しかし、内部サーバーを扱っていて、「正しい」証明書を取得するのが現実的でない場合は、次のようにしてWebサービスに証明書の問題を無視し、勇敢に兵士を任せてください。
最初の2つはラムダ式を使い、3番目は通常のコードを使います。最初の証明書を受け入れます。最後の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;
}
非常に単純な「包括的な」解決策はこれです。
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Sebastian-castaldiによる解決策はもう少し詳細です。
私は個人的には次の解決策が一番好きです。
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's Solution
Windows 2003を使用している場合は、これを試すことができます。
Microsoft管理コンソールを開きます([スタート] - > [ファイル名を指定して実行] - > mmc.exe)。
[ファイル] - > [スナップインの追加と削除]を選択します。
[スタンドアロン]タブで[追加]を選択します。
証明書スナップインを選択して、追加をクリックします。
ウィザードで、[コンピューターアカウント]を選択し、[ローカルコンピューター]を選択します。完了を押してウィザードを終了します。
[スナップインの追加と削除]ダイアログを閉じます。
証明書(ローカルコンピュータ)に移動して、インポートするストアを選択します。
証明書を発行した会社のルートCA証明書がある場合は、[信頼されたルート証明機関]を選択します。
サーバー自体の証明書がある場合は、[他の人]を選択します。
ストアを右クリックして、「すべてのタスク」 - >「インポート」を選択します。
ウィザードに従って、あなたが持っている証明書ファイルを提供してください。
その後、IISを再起動してWebサービスをもう一度呼び出してください。
誰もが盲目的に信頼して特定のホストだけに信頼例外を設定したくない場合は、次の解決策がより適切です。
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を呼び出します。
Microsoft SSL診断ツール は問題の特定に役立つかもしれません。
_ update _ リンクは現在修正されています。
Lukeはこれについてかなり良い記事を書きました。
理由(彼の記事からの引用(マイナスの呪い)) ".. ..上のコードの問題は、あなたの証明書が有効でないとうまくいかないということです。なぜ私は無効なSSL証明書でWebページに投稿するのでしょうか?私は安くて、私は自分のテストボックスへの証明書としてVerisignや他の ** - * sを支払う気がしませんでしたので、私は自己署名しました。私に投げられた素敵な例外:
System.Net.WebException 基礎となる接続が閉じられました。リモートサーバーとの信頼関係を確立できませんでした。
私はあなたのことを知りませんが、私にとって、例外はPOSTが失敗する原因となっていた私のコードの愚かなミスによって引き起こされるもののように見えました。それで私は検索を続け、あらゆる種類の奇妙なことを微調整してやっていました。私が*** nのことをグーグルした後に初めて、無効なSSL証明書に遭遇した後のデフォルトの振る舞いは、まさしくこの例外を投げることであることを私は見つけました。 ..」
私はこの問題に遭遇しました。私の解決策は、タイムサーバーに手動で同期することによってシステム時間を更新することでした。これを行うには、次のことができます。
Adjust Date/Time
を選択Internet Time
タブを選択してくださいChange Settings
をクリックUpdate Now
を選択私の場合、これは間違って同期していたので、正しく更新されるまでに数回クリックしなければなりませんでした。それが間違って更新し続けるならば、あなたはサーバドロップダウンから別のタイムサーバを使用することさえ試みることができます。
私はInternet Explorerの.NET
アプリで同様の問題を抱えていました。
信頼できるエディタの証明書に証明書(私の場合は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
ありがとう
これを試して:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
少なくとも4.5 .NET Frameworkで作業する必要があることに注意してください。
VSクライアント側でこの問題を抱えていて、サービス参照の追加に成功し、最初の呼び出しを実行しようとした人には、次の例外がありました。あなたは(私の場合のように)IPアドレスを持つエンドポイントURLを使用していて、この例外を得ました、そして、あなたはおそらくこのステップをしているサービス参照を再追加する必要があるでしょう:
再試行する :)。ありがとう
私はのようなURLでWebサーバーに対して実行しているこのエラーを持っていた:
a.b.domain.com
しかし、それに対する証明書がありませんでした、それで私はと呼ばれるDNSを得ました
a_b.domain.com
これがグーグルでトップになったので、ここでこの解決策にヒントを置いてください。
私の場合は、IIS 7を使用してVisual Studio環境で _ ssl _ をテストしようとしていました。
これは私がそれを機能させるためにやってしまったものです:
IISの右側の「バインド...」セクションにある自分のサイトの下で、ポート443に「https」バインドを追加し、「IIS Express開発証明書」を選択する必要がありました。
私のサイトの右側の「詳細設定...」セクションで、「有効なプロトコル」を「http」から「https」に変更する必要がありました。
[SSL設定]アイコンの下で、クライアント証明書に[同意する]を選択しました。
それから私はアプリプールをリサイクルしなければなりませんでした。
また、mmc.exeを使用してローカルホスト証明書を個人用ストアにインポートする必要がありました。
私のweb.config
ファイルはすでに正しく構成されているので、上記のすべてを整理した後、テストを続けることができました。
私のソリューション(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