System.Net.WebException in simple HTTPS Request
Asked Answered
F

3

6

I have got a problem with C# and a simple HTTPS-Request...

I want to request this URL: https://api.sipgate.com/v1/ In a webbrowser it works fine, but my C#-Code doesn't work :( Has anybody an idea what I did wrong? Thank you!

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());                
}

Here is the exception:

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:

Error in authentication because the other side has closed the transport stream.

Fate answered 18/3, 2017 at 11:11 Comment(0)
B
8

You are missing the support for 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");

Edit: Thank you @Crowcoder for pointing on this. In a production environment you should never accept any Certificate without validation. ServerCertificateValidationCallback provides a way to access information about the SSL Certificate that you couldn't normally. For example, the parameter error provides you specific certificate errors, like name mismatch. The parameter chain hands you the exact certificate chain sent by the server, which can be used to construct the certificate chain when system store has missing intermediate CA certificates.

ServicePointManager.ServerCertificateValidationCallback += 
    (s, cert, chain, error) =>
{
    return error == SslPolicyErrors.None;
};
Brinkmanship answered 18/3, 2017 at 11:20 Comment(3)
Thank you, but this new code throws the same exception: ServicePointManager.ServerCertificateValidationCallback += (s, cert, chain, error) => { return error == SslPolicyErrors.None; }; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; using (WebClient w = new WebClient()) { string ctn = w.DownloadString("api.sipgate.com/v1"); Console.WriteLine(ctn); }Fate
I updated my solution above, it works on my local machine. :)Brinkmanship
@bl4y: Thank you! I changed my .Net-Freamwork from 3.5 to 4.6.2 and now it works. :) In 3.5 is not "SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12"Fate
M
1

You could use the ServicePointManager to inspect the certificate and validate it is the one you expect, by thumbprint or subject name, for example.

But if you trust that site generally you install the certificate on the server.

In the Chrome dev tools, security tab, you can download the certificate and then install it on the server. You will need all certs in the chain as shown on the Certification Path tab.

enter image description here

Mini answered 18/3, 2017 at 11:53 Comment(0)
R
0

We had the same Error because the project had still the version 4.5 of .NET Framework. 4.5 uses TLS 1.0 by default. We changed to 4.8, which uses TLS 1.2, and it worked immediately.

Rightly answered 7/5 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.