我有一个简单的Web服务调用,由.NET(C#)2.0 Windows应用程序通过Visual Studio生成的Web服务代理生成,用于也使用C#(2.0)编写的Web服务。这已经工作了好几年了,并且在它运行的十几个地方继续这样做。
新网站上的新安装遇到问题。尝试调用Web服务时,它失败并显示消息:
无法为SSL / TLS安全建立信任关系 信道
Web服务的URL使用SSL(https://) - 但这已经在许多其他位置工作了很长时间(并且仍在继续)。
我在哪里看?这可能是Windows和.NET之间的安全问题吗?如果是这样,我在哪里建立信任关系?我迷路了!
答案 0 :(得分:346)
以下代码段将修复您正在呼叫的服务器上的SSL证书有问题的情况。例如,它可能是自签名的,或者证书与服务器之间的主机名可能不匹配。
这是危险的,如果您正在直接控制之外调用服务器,因为您无法确定是否正在与您认为已连接的服务器通话。但是,如果您正在处理内部服务器并且获得“正确”证书是不切实际的,请使用以下命令告知Web服务忽略证书问题并勇敢地参与其中。
前两个使用lambda表达式,第三个使用常规代码。第一个接受任何证书。最后两个至少检查证书中的主机名是否是您期望的主机名 ...希望你觉得有用
//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;
}
答案 1 :(得分:160)
非常简单的“全能”解决方案就是:
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
塞巴斯蒂安 - 卡斯塔尔迪的解决方案更为详细。
答案 2 :(得分:157)
思考(基于过去的痛苦):
答案 3 :(得分:32)
我个人最喜欢以下解决方案:
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
...然后在您请求获取错误之前,请执行以下操作
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };
后找到了这个
答案 4 :(得分:18)
如果您使用的是Windows 2003,可以试试这个:
打开Microsoft管理控制台 (开始 - >运行 - > mmc.exe);
选择文件 - >添加/删除管理单元;
在Standalone选项卡中,选择Add;
选择“证书”管理单元,然后选择 单击添加;
在向导中,选择“计算机” 帐户,然后选择本地 电脑。按完成结束 向导;
关闭“添加/删除管理单元”对话框;
导航到证书(本地 电脑)并选择一家商店 输入:
如果您拥有根CA证书 对于发行的公司 证书,选择“受信任的根” 认证机构;
如果你有证书 服务器本身,选择其他人
右键单击商店,然后选择全部 任务 - >导入
按照向导提供 您拥有的证书文件;
之后,只需重新启动IIS并尝试 再次调用Web服务。
答案 5 :(得分:15)
如果您不想盲目地信任每个人并仅为某些主机设置信任例外,则以下解决方案更合适。
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。
答案 6 :(得分:7)
Microsoft的SSL Diagnostics Tool可能有助于确定问题。
更新此链接现已修复。
答案 7 :(得分:6)
卢克写了一篇关于这篇文章的相当不错的文章。 非常直接..试一试
原因(引自他的文章(减去诅咒)) ” .. 上面代码的问题是,如果您的证书无效,它将不起作用。为什么我要发布到具有无效SSL证书的网页?因为我便宜而且我不想支付Verisign或其他 ** - * s来获得我的测试盒的证书所以我自己签了它。当我发出请求时,我得到了一个可爱的例外:
<强> System.Net.WebException 强> 底层连接已关闭。无法与远程服务器建立信任关系。
我不了解你,但对我而言,异常看起来像是由于我的代码中的一个愚蠢的错误导致POST失败而引起的。所以我一直在搜索,调整和做各种奇怪的事情。只有在我搜索了***之后,才发现遇到无效SSL证书后的默认行为是抛出这个异常。 ..“
答案 8 :(得分:3)
我刚遇到这个问题。我的决心是通过手动同步到时间服务器来更新系统时间。要做到这一点,你可以:
Adjust Date/Time
Internet Time
标签Change Settings
Update Now
在我的情况下,这是同步错误所以我必须多次点击它才能正确更新。如果它继续不正确地更新,您甚至可以尝试使用服务器下拉列表中的其他时间服务器。
答案 9 :(得分:3)
我在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
感谢
答案 10 :(得分:2)
试试这个:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
请注意,您必须至少使用4.5 .NET framework
答案 11 :(得分:1)
我在使用url的网络服务器上运行此错误:
a.b.domain.com
但没有证书,所以我得到了一个名为
的DNSa_b.domain.com
这里只是提示这个解决方案,因为这在google中名列前茅。
答案 12 :(得分:1)
添加此内容:
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;}
在您致电该服务的行之前
答案 13 :(得分:1)
对于那些通过VS客户端遇到此问题的人,一旦成功添加服务引用并尝试执行第一次调用就会遇到此异常: “底层连接已关闭:无法为SSL / TLS安全通道建立信任关系” 如果您正在使用(就像我的情况一样)具有IP地址的端点URL并获得此异常,那么您可能需要重新添加服务引用,执行以下步骤:
再试一次:)。 感谢
答案 14 :(得分:0)
我使用了一段时间的变体,如果有帮助的话。
调用方必须明确请求需要不受信任的证书,并在完成后将回调放回默认状态。
/// <summary>
/// Helper method for returning the content of an external webpage
/// </summary>
/// <param name="url">URL to get</param>
/// <param name="allowUntrustedCertificates">Flags whether to trust untrusted or self-signed certificates</param>
/// <returns>HTML of the webpage</returns>
public static string HttpGet(string url, bool allowUntrustedCertificates = false) {
var oldCallback = ServicePointManager.ServerCertificateValidationCallback;
string webPage = "";
try {
WebRequest req = WebRequest.Create(url);
if (allowUntrustedCertificates) {
// so we can query self-signed certificates
ServicePointManager.ServerCertificateValidationCallback =
((sender, certification, chain, sslPolicyErrors) => true);
}
WebResponse resp = req.GetResponse();
using (StreamReader sr = new StreamReader(resp.GetResponseStream())) {
webPage = sr.ReadToEnd().Trim();
sr.Close();
}
return webPage;
}
catch {
// if the remote site fails to response (or we have no connection)
return null;
}
finally {
ServicePointManager.ServerCertificateValidationCallback = oldCallback;
}
}
答案 15 :(得分:0)
我的解决方案(VB.Net,此应用程序的“ staging”(UAT)版本需要使用“ staging”证书,但在请求进入实时站点后不影响请求):
table_src = html.text.split('<div class="overthrow table_container"
id="div_team-stats-per_game">')[1].split('</table>')[0] + '</table>'
table = BeautifulSoup(table_src, 'lxml')
答案 16 :(得分:0)
就我而言,我尝试使用IIS 7在Visual Studio环境中测试 SSL 。
这是我最终要做的工作:
在IIS右侧“绑定...”部分的网站中,我必须将“https”绑定添加到端口443并选择“IIS Express开发证书”。
< / LI>在我右侧“高级设置...”部分的网站中,我必须将“启用的协议”从“http”更改为“https”。
在“SSL设置”图标下,我为客户端证书选择了“接受”。
然后我不得不回收应用池。
我还必须使用mmc.exe将本地主机证书导入我的个人商店。
我的web.config
文件已经配置正确,所以在我完成上述所有操作后,我就可以继续测试了。
答案 17 :(得分:-4)
如果不是工作错误的sertificate,当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运行得非常好