41

使用 Visual Studio 2005 - C# 2.0、System.Net.WebClient.UploadData(Uri address, byte[] data) Windows Server 2003

所以这是代码的精简版本:

static string SO_method(String fullRequestString)
{
    string theUriStringToUse = @"https://10.10.10.10:443"; // populated with real endpoint IP:port
    string proxyAddressAndPort = @"http://10.10.10.10:80/"; // populated with a real proxy IP:port
    Byte[] utf8EncodedResponse; // for the return data in utf8
    string responseString; // for the return data in utf16

    WebClient myWebClient = new WebClient(); // instantiate a web client
    WebProxy proxyObject = new WebProxy(proxyAddressAndPort, true);// instantiate & popuylate a web proxy
    myWebClient.Proxy = proxyObject; // add the proxy to the client
    myWebClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); // stick some stuff in the header

    UTF8Encoding utf8Encoding = new UTF8Encoding(false);// create a utf8 encoding
    Byte[] utf8EncodedRequest = HttpUtility.UrlEncodeToBytes(fullRequestString, utf8Encoding); // convert the request data to a utf8 byte array

    try
    {
        utf8EncodedResponse = myWebClient.UploadData(theUriStringToUse, "POST", utf8EncodedRequest); // pass the utf8-encoded byte array
        responseString = utf8Encoding.GetString(utf8EncodedResponse); // get a useable string out of the response
    }
    catch (Exception e)
    {
        // some other error handling
        responseString = "<CommError><![CDATA[" + e.ToString() + "]]></CommError>";// show the basics of the problem
    }
    return responseString;// return whatever ya got
}

这是我得到的错误:

基础连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。

当请求发出时,我没有太多控制权来查看发生了什么。我被告知它正在到达正确的目的地并且存在“证书错误”。这可能是因为我的请求中的 IP 地址与其解析到的 URL 之间存在文字不匹配。我有多个 IP 我应该轮询,因此指定 URL 将不起作用。我没有附上证书——我也不应该根据端点所有者的说法。对于“他们”来说,证书错误是“正常的”,我应该忽略它。

有问题的证书据说是我们服务器上“就在那里”的众多威瑞信证书之一。我看到的忽略证书错误的示例似乎都暗示请求者正在附加特定的 x509 证书(我不是)。

我查看了.net WebService,绕过 ssl 验证!which kinda-sorta 描述了我的问题 - 除了它也有点不,因为我不知道我应该参考哪个证书(如果有的话)。

有没有办法让我在不知道/关心导致问题的证书的情况下忽略错误?

  • 并且拜托-孩子手套,小词和“傻瓜”代码,因为我不是一个重量级的击球手。

  • 此流量通过专用线路 - 所以我的理解是,忽略证书错误并不像它是开放的互联网流量那么重要。

4

6 回答 6

60

SSL证书是为一台机器建立信任关系的。如果您输入一个 IP 地址并最终与另一个 IP 地址通话,这听起来与 DNS 劫持安全故障相同,这是 SSL 旨在帮助您避免的那种事情——也许是您不想忍受的事情从他们”。

如果您最终可能与多台机器交谈(理想情况下,它们会让您看起来像是一台机器),那么您将需要为每台可能的机器提供一个证书来启动信任。

要忽略信任(我只需要在开发场景中临时这样做),以下代码段可能对您有用,但我强烈建议您在使用之前考虑忽略信任的影响:

public static void InitiateSSLTrust()
{
    try
    {
        //Change SSL checks so that all checks pass
        ServicePointManager.ServerCertificateValidationCallback =
           new RemoteCertificateValidationCallback(
                delegate
                { return true; }
            );
    }
    catch (Exception ex)
    {
        ActivityLog.InsertSyncActivity(ex);
    }
}
于 2009-08-19T16:49:53.087 回答
20

我意识到这是一篇旧文章,但我只是想表明有一种更简便的方法(使用 .NET 3.5+ 及更高版本)。

也许这只是我的强迫症,但我想尽可能地减少这段代码。这似乎是最短的方法,但我还在下面列出了一些更长的等价物:

// 79 Characters (72 without spaces)
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;

.NET 2.0 中的最短路径(这是问题的具体要求)

// 84 Characters
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

不幸的是 lambda 方式需要你定义参数,否则它可能会更短。

如果您需要更长的路,这里有一些额外的选择:

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, errors) => true;

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

// 255 characters - lots of code!
ServicePointManager.ServerCertificateValidationCallback =
    new RemoteCertificateValidationCallback(
        delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        });
于 2014-06-26T01:37:27.123 回答
12

这在某种程度上是我们正在使用的代码(尚未完善 - 我认为我的错误处理设置不正确,但它应该很接近)基于 thomas 的建议(虽然这是 .NET 4.0 代码):

var sslFailureCallback = new RemoteCertificateValidationCallback(delegate { return true; });

try
{

    if (ignoreSslErrors)
    {
        ServicePointManager.ServerCertificateValidationCallback += sslFailureCallback;
    }

    response = webClient.UploadData(Options.Address, "POST", Encoding.ASCII.GetBytes(Options.PostData));

}
catch (Exception err)
{
    PageSource = "POST Failed:\r\n\r\n" + err;
    return PageSource;
}
finally
{
    if (ignoreSslErrors)
    {
        ServicePointManager.ServerCertificateValidationCallback -= sslFailureCallback;
    }
}
于 2011-07-08T20:23:58.087 回答
8

此代码比您预期的要广泛得多。它是全过程的。该进程可能是本机上的 exe、IIS,甚至是 DLLHost.exe。调用它之后,有一个 finally 块,通过删除总是返回 true 的委托来恢复正常。

于 2009-08-25T20:05:22.837 回答
4

我想在不全局停用它的情况下禁用特定域的 SSL 验证,因为可能有其他不应该受到影响的请求正在运行,所以我想出了这个解决方案(请注意 uri 是类中的变量:

        private byte[] UploadValues(string method, NameValueCollection data)
        {
            var client = new WebClient();

            try
            {
                ServicePointManager.ServerCertificateValidationCallback +=
                    ServerCertificateValidation;

                returnrclient.UploadValues(uri, method, parameters);

            }
            finally
            {
                ServicePointManager.ServerCertificateValidationCallback -=
                    ServerCertificateValidation;
            }
        }

        private bool ServerCertificateValidation(object sender,
            X509Certificate certificate, X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
        {
            var request = sender as HttpWebRequest;
            if (request != null && request.Address.Host.Equals(
                this.uri.Host, StringComparison.OrdinalIgnoreCase))
                return true;
            return false;
        }
于 2016-10-06T15:29:23.043 回答
1

这是使 WebClient 忽略 SSL 证书的 VB.net 代码。

Net.ServicePointManager.ServerCertificateValidationCallback = New Net.Security.RemoteCertificateValidationCallback(Function() True)
于 2017-03-14T19:06:23.563 回答