如何使用 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());
如果提供的 url 是 https://
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时如何获取位置标头