【问题标题】:System.Net.WebException when using WebClient: Can not create SSL/TLS secure channel使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道
【发布时间】:2015-05-26 15:30:12
【问题描述】:

当我执行以下代码时

System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => {
    return true;
};
var webClient = new WebClient();
var s = webClient.DownloadString("https://jtlplugins.x-volution.de/api.php?apikey=yS5VS7OiG1ukiIqLzCSYuFCjeF1qSskKOQeCtVxh&do=pruefe_app&cappid=123&chardwareid=DC0D-BFEA-6F79-58DE-21E9-BA3A-B288-C46F&clizenzschluessel=123");

我总是收到 System.Net.WebException:无法创建 SSL/TLS 安全通道

当我执行此操作时

https://jtlplugins.x-volution.de/api.php?apikey=yS5VS7OiG1ukiIqLzCSYuFCjeF1qSskKOQeCtVxh&do=pruefe_app&cappid=123&chardwareid=DC0D-BFEA-6F79-58DE-21E9-BA3A-B288-C46F&clizenzschluessel=123

例如直接在 Firefox 或 Internet Explorer 中,它可以工作并返回结果。

如果我的代码也像在浏览器中一样执行,我该怎么办?

我已阅读 stackoverflow 中有关此问题的其他帖子 - 但它们并没有解决我的问题 :-(

【问题讨论】:

  • 可能不应该发布未经编辑的 api 密钥。
  • 您想要远程服务器使用的安全协议吗?您可能必须明确设置。

标签: c# ssl webclient


【解决方案1】:

下面是一个继承的 WebClient 类,它解决了很多像这样的一般问题......

using System;
using System.Net;
namespace YourProgram.Web
{
    public class WebClient : System.Net.WebClient
    {
        public WebClient()
        {
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            this.container = new CookieContainer();
        }
        public WebClient(CookieContainer container)
        {
            this.container = container;
        }

        public CookieContainer CookieContainer
        {
            get { return container; }
            set { container = value; }
        }

        private CookieContainer container = new CookieContainer();

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest r = base.GetWebRequest(address);
            var request = r as HttpWebRequest;
            if (request != null)
            {
                request.CookieContainer = container;
            }
            return r;
        }

        protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
        {
            WebResponse response = base.GetWebResponse(request, result);
            ReadCookies(response);
            return response;
        }

        protected override WebResponse GetWebResponse(WebRequest request)
        {
            WebResponse response = base.GetWebResponse(request);
            ReadCookies(response);
            return response;
        }

        private void ReadCookies(WebResponse r)
        {
            var response = r as HttpWebResponse;
            if (response != null)
            {
                CookieCollection cookies = response.Cookies;
                container.Add(cookies);
            }
        }
    }
}

享受...

【讨论】:

    【解决方案2】:

    如果你关闭 fiddler(如果你已经打开它)并添加以下异常应该会消失

    ServicePointManager.Expect100Continue = true;                
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    

    或者至少当我像这样尝试你的代码时它对我有用

    try
    {
         ServicePointManager.Expect100Continue = true;                
         ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    
         ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    
         var webClient = new WebClient();
    
         var s = webClient.DownloadString("https://jtlplugins.x-volution.de/api.php?apikey=yS5VS7OiG1ukiIqLzCSYuFCjeF1qSskKOQeCtVxh&do=pruefe_app&cappid=123&chardwareid=DC0D-BFEA-6F79-58DE-21E9-BA3A-B288-C46F&clizenzschluessel=123");
    
         MessageBox.Show("Result" + s);
    }
    catch(Exception ex)
    { 
      MessageBox.Show(ex.Message); 
    }
    
    • 不安全的代码警告 - 尽管我假设您已经知道这一点并且不是您的代码收到 WebException 的原因,但在最初发布此问题后的几十年内,我仍向潜在的未来读者添加警告。代码:

      System.Net.ServicePointManager.ServerCertificateValidationCallback =(发件人,证书,链,错误)=> { 返回真; };

    将忽略任何证书验证错误,因此根据定义并不完全安全。请看问题C# Ignore certificate errors?

    【讨论】:

    • ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 行不安全
    • @ympostor 是的,我相信 OP 在最初发布问题时已经假设了这一点(请参阅原始问题中的 lambda 表达式)。问题更多的是为什么这段代码会抛出一个 WebException,添加缺少的属性可以解决。因此,我向未来的读者添加了一个警告... PS 感谢您的反对...
    猜你喜欢
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 2021-12-13
    • 2014-12-26
    相关资源
    最近更新 更多