如何使用 WebRequest 访问使用 HTTPS 的 SSL 加密站点?

Posted

技术标签:

【中文标题】如何使用 WebRequest 访问使用 HTTPS 的 SSL 加密站点?【英文标题】:How do I use WebRequest to access an SSL encrypted site using HTTPS? 【发布时间】:2010-10-08 07:55:08 【问题描述】:

我正在编写一个从用户提供的 URL 读取内容的程序。我的问题出在如下代码中:

Uri uri = new Uri(url);
WebRequest webRequest = WebRequest.Create(uri);
WebResponse webResponse = webRequest.GetResponse();
ReadFrom(webResponse.GetResponseStream());

如果提供的 urlhttps:// URL,这将是破坏性的。任何人都可以帮助我更改此代码,以便它可以与 SSL 加密内容一起使用。谢谢。

【问题讨论】:

【参考方案1】:

您的操作方式正确,但用户可能会向安装了无效 SSL 证书的网站提供网址。如果在发出实际 Web 请求之前输入此行,则可以忽略这些证书问题:

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

AcceptAllCertifications 定义为

public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)

    return true;

【讨论】:

感谢您的回答!为了避免一些无用的代码,我这样使用它:ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true; 谢谢,先生,您帮助了我。 F# 让这一切变得如此简单:ServicePointManager.ServerCertificateValidationCallback <- Security.RemoteCertificateValidationCallback (fun _ _ _ _ -> true) 我更喜欢+= delegate return true; 请注意与此方法相关的潜在风险。请参阅***.com/a/6613434/2969615 了解更多信息。【参考方案2】:

这个对我有用:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

【讨论】:

默认值为“Ssl2 | Tls”。我只在我的服务器上启用了 Tls 1.1 和 1.2。这确实解决了问题!对于 Linux 上带有 nginx 的 LetsEncrypt,协议在此处定义:/etc/letsencrypt/options-ssl-nginx.conf 我相信这是处理不同的问题。这与无效证书无关,而是更高的 TLS 版本。【参考方案3】:

您会对此链接感兴趣:http://msdn.microsoft.com/en-us/library/ds8bxk2a.aspx

对于 http 连接,WebRequest 和 WebResponse 类使用 SSL 与支持 SSL 的 Web 主机通信。使用 SSL 的决定是由 WebRequest 类根据给定的 URI 做出的。如果 URI 以“https:”开头,则使用 SSL;如果 URI 以“http:”开头,则使用未加密的连接。

【讨论】:

您的回答暗示问题中的代码应该可以工作?【参考方案4】:

正如@LukeDuff 投票最多的回答正确所说,服务器很可能使用了无效或不受信任(或自签名,在技术上也是不受信任的)证书。但是答案盲目地接受任何证书。更糟糕的是,即使是任何站点的任何证书,甚至是您期望受信任和有效证书的站点。这是一个安全漏洞。

在实施ServicePointManager.ServerCertificateValidation callback 时,应该验证证书。例如。通过根据已知值检查证书的哈希:

using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
ServicePointManager.ServerCertificateValidationCallback +=
    (sender, certificate, chain, errors) =>
    
        return
            (errors == SslPolicyErrors.None) ||
            certificate.GetCertHashString(HashAlgorithmName.SHA256).Equals(
                "EB8E0B28AE064ED58CBED9DAEB46CFEB3BD7ECA677...");
    ;

对于X509Certificate.GetCertHashString overload that takes HashAlgorithmName.SHA256,您需要.NET 4.8。在旧版本上使用返回 SHA-1 哈希的 the parameter-less overload。


基于Is it safe to test the X509Certificate.Thumbprint property when you know an invalid certificate is safe?

VB.NET 版本代码见Accept self-signed TLS/SSL certificate in VB.NET

【讨论】:

以上是关于如何使用 WebRequest 访问使用 HTTPS 的 SSL 加密站点?的主要内容,如果未能解决你的问题,请参考以下文章

.NET 3.5CF WebRequest 到 Slim 框架

在powershell中使用Invoke-WebRequest重定向URL时如何获取位置标头

检测 WebRequest 的 HTTP 代理错误

webRequest

Sharepoint Online 上禁止 WebRequest

使用WebRequest对象调用新浪天气预报<转>