我有一个简单的web服务调用,由。net (c#) 2.0 Windows应用程序生成,通过Visual Studio生成的web服务代理,用于同样用c#(2.0)编写的web服务。这种方法已经有效了好几年,并且在十几个正在运行的地方继续有效。

在新地点的新安装遇到了问题。当试图调用web服务时,它失败了,消息说:

无法为SSL/TLS安全建立信任关系 通道

web服务的URL使用SSL (https://)——但这已经在许多其他位置工作了很长时间(并继续这样做)。

我该往哪里看?这可能是Windows和。net之间的安全问题,是此安装独有的吗?如果是,我在哪里建立信任关系?我迷路了!


当前回答

我刚刚遇到了这个问题。我的解决方案是通过手动同步时间服务器来更新系统时间。要做到这一点,你可以:

右键单击任务栏中的时钟 选择“调整日期/时间” 选择“Internet Time”选项卡 单击“更改设置” 选择立即更新

在我的情况下,这是不正确的同步,所以我必须点击它几次才能正确更新。如果它继续不正确地更新,您甚至可以尝试从服务器下拉菜单中使用不同的时间服务器。

其他回答

Luke写了一篇关于这方面的好文章。 非常直截了当。试试吧

卢克的解决方案

原因(引用自他的文章(含诅咒)) “. . 上面的代码的问题是,如果您的证书无效,它将无法工作。为什么我要发布到一个网页与无效的SSL证书?因为我很便宜,我不想付钱给Verisign或其他** *的人对我的测试箱进行认证,所以我自己签名了。当我发送请求时,我得到了一个可爱的例外:

System.Net.WebException 底层连接被关闭。无法与远程服务器建立信任关系。

我不知道你怎么想,但对我来说,这个异常看起来像是由我的代码中一个愚蠢的错误引起的,导致POST失败。所以我一直在寻找,调整,做各种奇怪的事情。只有在我谷歌了***n的东西,我发现遇到无效的SSL证书后的默认行为是抛出这个异常。 . .”

添加:

 ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;}

就在你呼叫服务之前

如果您不想盲目地信任所有人,只对某些主机设置信任例外,那么下面的解决方案更合适。

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。当你的应用启动时启用托管主机。

如果没有工作坏证书,当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运行得很好

“一网打尽”的简单解决方案是:

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

sebastian-castaldi的解决方案更详细一些。