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.
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;
};
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With