在向远程web服务请求web服务期间,我得到以下错误:

无法为SSL/TLS安全通道建立信任关系。——> System.Security.Authentication.AuthenticationException:根据验证程序,远端证书无效。

是否有办法忽略此错误并继续?

远程证书似乎没有签名。

我连接到的站点是www.czebox.cz——所以请随意访问该站点,并注意即使浏览器也会抛出安全异常。


当前回答

为了进一步扩展bigignum的帖子-理想情况下,您需要一个解决方案,可以模拟您在生产中看到的条件,修改您的代码不会做到这一点,如果您忘记在部署之前将代码取出,则可能会带来危险。

您将需要某种类型的自签名证书。如果你知道你在做什么,你可以使用BIGNUM发布的二进制文件,但如果你不知道,你可以去寻找证书。如果你正在使用IIS Express,你已经有了其中一个,你只需要找到它。打开火狐或其他你喜欢的浏览器,进入你的开发网站。您应该能够从URL栏查看证书信息,并且根据您的浏览器,您应该能够将证书导出到一个文件。

接下来,打开MMC.exe,并添加Certificate管理单元。将证书文件导入“受信任的根证书颁发机构”存储区,这就是您所需要的全部内容。重要的是要确保它进入那个商店,而不是其他像“私人”的商店。如果您不熟悉MMC或证书,有许多网站提供如何做到这一点的信息。

现在,您的计算机作为一个整体将隐式地信任它自己生成的任何证书,您不需要添加代码来专门处理这一点。当您转移到生产环境时,它将继续工作,前提是您在那里安装了适当的有效证书。不要在生产服务器上这样做——那样会很糟糕,而且除了服务器上的客户端之外,它对任何其他客户端都不起作用。

其他回答

允许所有证书是非常强大的,但也可能是危险的。如果您希望只允许有效的证书加上某些特定的证书,可以这样做。

net核心:

using (var httpClientHandler = new HttpClientHandler())
{
    httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;   //Is valid
        }

        if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
        {
            return true;
        }
        return false;
    };

    using (var httpClient = new HttpClient(httpClientHandler))
    {
        var httpResponse = httpClient.GetAsync("https://example.com").Result;
    }
}

net框架:

System.Net.ServicePointManager.ServerCertificateValidationCallback += delegate (
    object sender,
    X509Certificate cert,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
    {
        return true;   //Is valid
    }

    if (cert.GetCertHashString() == "99E92D8447AEF30483B1D7527812C9B7B3A915A7")
    {
        return true;
    }

    return false;
};

更新:

如何在Chrome中获取cert.GetCertHashString()值:

在地址栏中单击“安全”或“不安全”。

然后单击Certificate -> Details -> Thumbprint并复制该值。记得执行cert.GetCertHashString(). tolower()。

如果直接使用套接字并作为客户端进行身份验证,则Service Point Manager回调方法将不起作用。以下是对我有效的方法。请仅用于测试目的。

var activeStream = new SslStream(networkStream, false, (a, b, c, d) => { return true; });
await activeStream.AuthenticateAsClientAsync("computer.local");

这里的关键是在SSL流的构造函数中提供远程证书验证回调。

为了进一步扩展bigignum的帖子-理想情况下,您需要一个解决方案,可以模拟您在生产中看到的条件,修改您的代码不会做到这一点,如果您忘记在部署之前将代码取出,则可能会带来危险。

您将需要某种类型的自签名证书。如果你知道你在做什么,你可以使用BIGNUM发布的二进制文件,但如果你不知道,你可以去寻找证书。如果你正在使用IIS Express,你已经有了其中一个,你只需要找到它。打开火狐或其他你喜欢的浏览器,进入你的开发网站。您应该能够从URL栏查看证书信息,并且根据您的浏览器,您应该能够将证书导出到一个文件。

接下来,打开MMC.exe,并添加Certificate管理单元。将证书文件导入“受信任的根证书颁发机构”存储区,这就是您所需要的全部内容。重要的是要确保它进入那个商店,而不是其他像“私人”的商店。如果您不熟悉MMC或证书,有许多网站提供如何做到这一点的信息。

现在,您的计算机作为一个整体将隐式地信任它自己生成的任何证书,您不需要添加代码来专门处理这一点。当您转移到生产环境时,它将继续工作,前提是您在那里安装了适当的有效证书。不要在生产服务器上这样做——那样会很糟糕,而且除了服务器上的客户端之外,它对任何其他客户端都不起作用。

这适用于。net Core。 调用Soap客户端:

client.ClientCredentials.ServiceCertificate.SslCertificateAuthentication =
                new X509ServiceCertificateAuthentication()
                {
                    CertificateValidationMode = X509CertificateValidationMode.None,
                    RevocationMode = X509RevocationMode.NoCheck
                };  

IgnoreBadCertificates方法:

//I use a method to ignore bad certs caused by misc errors
IgnoreBadCertificates();

// after the Ignore call i can do what ever i want...
HttpWebRequest request_data = System.Net.WebRequest.Create(urlquerystring) as HttpWebRequest;

/*
and below the Methods we are using...
*/

/// <summary>
/// Together with the AcceptAllCertifications method right
/// below this causes to bypass errors caused by SLL-Errors.
/// </summary>
public static void IgnoreBadCertificates()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);
}  

/// <summary>
/// In Short: the Method solves the Problem of broken Certificates.
/// Sometime when requesting Data and the sending Webserverconnection
/// is based on a SSL Connection, an Error is caused by Servers whoes
/// Certificate(s) have Errors. Like when the Cert is out of date
/// and much more... So at this point when calling the method,
/// this behaviour is prevented
/// </summary>
/// <param name="sender"></param>
/// <param name="certification"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns>true</returns>
private static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}