【问题标题】:System.Net.WebException in simple HTTPS Request简单 HTTPS 请求中的 System.Net.WebException
【发布时间】:2017-03-18 11:11:02
【问题描述】:

我遇到了一个 C# 问题和一个简单的 HTTPS 请求...

我想请求这个 URL:https://api.sipgate.com/v1/ 在网络浏览器中它工作正常,但我的 C#-Code 不工作 :( 有人知道我做错了什么吗?谢谢!

using System.Net;
using System.IO;

// [...]

WebRequest req = WebRequest.Create("https://api.sipgate.com/v1");
req.ContentType = "application/json";

try {
    WebResponse res = req.GetResponse();  // Exception here...
    Stream content = res.GetResponseStream();
    Console.WriteLine((new StreamReader(content)).ReadToEnd());
} catch (Exception e) {
    Console.WriteLine(e.ToString());                
}

这是一个例外:

System.Net.WebException: Die zugrunde liegende Verbindung wurde geschlossen: Unerwarteter Fehler beim Senden.. ---> System.IO.IOException: Fehler bei Authentifizierung, da die Gegenseite den Transportstream geschlossen hat.
   bei System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   bei System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   bei System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   bei System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   bei System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   bei System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   bei System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   bei System.Net.ConnectStream.WriteHeaders(Boolean async)
   --- Ende der internen Ausnahmestapelüberwachung ---
   bei System.Net.HttpWebRequest.GetResponse()
   bei Sipgate_Test.Program.Main(String[] args) in c:\users\abc\documents\visual studio 2017\Projects\def\hij\Program.cs:Zeile 24.

System.Net.WebException:

认证错误,因为对方已经关闭了传输流。

【问题讨论】:

    标签: c# .net web https request


    【解决方案1】:

    您缺少对 SSL 的支持。

    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
    
    using (WebClient Client = new WebClient())
        string Content = Client.DownloadString("https://api.sipgate.com/v1");
    

    编辑: 感谢@Crowcoder 指出这一点。在生产环境中,您不应该接受任何未经验证的证书。 ServerCertificateValidationCallback 提供了一种访问 SSL 证书信息的方法,这是您通常无法访问的。 例如,参数error 会为您提供特定的证书错误,例如名称不匹配。参数chain为你提供服务器发送的确切证书链,当系统存储缺少中间CA证书时,可用于构建证书链。

    ServicePointManager.ServerCertificateValidationCallback += 
        (s, cert, chain, error) =>
    {
        return error == SslPolicyErrors.None;
    };
    

    【讨论】:

    • 谢谢,但是这个新代码抛出了同样的异常:ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, error) => { return error == SslPolicyErrors.None; }; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;使用 (WebClient w = new WebClient()) { string ctn = w.DownloadString("api.sipgate.com/v1"); Console.WriteLine(ctn); }
    • 我更新了上面的解决方案,它可以在我的本地机器上运行。 :)
    • @bl4y:谢谢!我将 .Net-Freamwork 从 3.5 更改为 4.6.2,现在它可以工作了。 :) 在 3.5 中不是“SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12”
    【解决方案2】:

    您可以使用ServicePointManager 检查证书并验证它是您期望的证书,例如通过指纹或主题名称。

    但是,如果您通常信任该站点,则通常将证书安装在服务器上。

    在 Chrome 开发工具的安全选项卡中,您可以下载证书,然后将其安装到服务器上。您将需要链中的所有证书,如Certification Path 选项卡上所示。

    【讨论】:

      猜你喜欢
      • 2017-10-22
      • 1970-01-01
      • 2011-04-23
      • 2018-07-28
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 2013-01-15
      相关资源
      最近更新 更多