Troubleshoot TLS1.2 in .NET 4.7.2 / 4.8 with wireshark - vb.net

We have problem with .NET application which runs fine on development PC (win10)
but when deployed to "Windows server 2016" production env it reports:
System.Net.WebException: The request was aborted: Could not create
SSL/TLS secure channel.
wireshark difference in Dev and Prod Env
On Dev (Win10) there is "Certificate,Client Key Exchange" after "Server Key Exchange" packet
On Prod (srv 2016) there is "TCP Spurious Retransmission" after "Server Key Exchange" as on screenshot
Tried with .NET 4.7.2 and 4.8 same error, how to proceed ?
It looks like there is problem on production server when PFX cert is used
Dim request As HttpWebRequest = CType(WebRequest.Create("https://obt2b1.service.com/cords/api/"), HttpWebRequest)
request.Method = WebRequestMethods.Http.Post
request.Accept = "application/xml"
request.ContentType = "application/xml"
'Use x509 PFX
request.ClientCertificates.Add(getCert())
request.KeepAlive = True
request.CachePolicy = New System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore)
request.Timeout = 1000000
request.AllowAutoRedirect = True
Dim dataStream As Byte() = Encoding.UTF8.GetBytes(xml_send)
request.ContentLength = dataStream.Length
ServicePointManager.Expect100Continue = true
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
'Here the error "System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel." is reported
Dim _stream As Stream = request.GetRequestStream()
...
Private Function getCert() As X509Certificate2
Dim collection As New X509Certificate2Collection()
collection.Import("C:\pfx\test.pfx", "xxx", X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.UserKeySet Or X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.Exportable)
Return collection(0)
End Function
EDITED ... SecurityProtocol moved up same thing
ServicePointManager.Expect100Continue = true
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim request As HttpWebRequest = CType(WebRequest.Create("https://obt2b1.service.com/cords/api/"), HttpWebRequest)
request.Method = WebRequestMethods.Http.Post
request.Accept = "application/xml"
request.ContentType = "application/xml"
'Use x509 PFX
request.ClientCertificates.Add(getCert())
request.KeepAlive = True
request.CachePolicy = New System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore)
request.Timeout = 1000000
request.AllowAutoRedirect = True
Dim dataStream As Byte() = Encoding.UTF8.GetBytes(xml_send)
request.ContentLength = dataStream.Length
'GetRequestStream() gets the error "System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel." is reported
Dim _stream As Stream = request.GetRequestStream()

OK after an almost week of testing I found a solution.
Things that I tried:
windows server 2012R2 (working no problem)
windows server 2016 (not working)
windows server 2019 (not working)
I tried to enable ALL ciphers and ALL settings in IIS Cryto 3.2 - didn't help.
Problem was in worker process on the IIS, you need to enable "Load User Profile" to True
IIS -> Application Pools -> (choose pool) -> Advanced Settings ...
Change "Load User Profile" from false to true ...
After that I start IIS Crypto 3.2 set all setting to restrictive as it was before

Related

Unexpected error occurred on a receive using API on my Wix site

I've made an experimental email and password system using post requests to my Wix site API and I've verified it works through curl and postman. When trying to use it in my VB.NET app however I get the error: "The underlying connection was closed: An unexpected error occurred on a receive." I already previously ran into a "Could not create SSL/TLS secure channel" error but that was resolved when I moved the .NET framework for the project to 4.7.1 and made sure SecurityProtocol was set to SystemDefault as Wix seems to use TLS 1.3. Now however I'm getting this error on receive that I have no idea how to resolve as everything in the request seems to look ok:
ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault
Dim req As HttpWebRequest = DirectCast(WebRequest.Create(New Uri("https://xxxxx.com/mysite/_functions/check?email=" & email & "&pass=" & LCase(passHash))), HttpWebRequest)
req.Method = "POST"
req.ContentType = "none"
req.ContentLength = 0
req.Host = "test"
req.KeepAlive = True
Dim result As HttpWebResponse = req.GetResponse()
The error is thrown when running 'req.GetReponse()'.
After looking at countless versions of sample code for .NET POST requests and questions about this error but everyone seems to suggest setting the security prococol type, which I have done and setting it as the system default is the only way I don't get an internal server error status. Another was setting KeepAlive to false, which I have also tried but didn't make any difference.
What could be the problem here? Here is what's included in the postman header if this is of help:
Ok so eventually I ended up changing my code to use GetResponseAsync() instead of GetResponse() (not that it made any difference to the problem) and set the protocol type back to Tls12 on .NET 4.8. In the end it seemed that having req.Host set was what was causing the issue with the response, Wix doesn't seem to like it. I also added some extra settings to the request but ultimately they make no difference to the response. Here is the final working code:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim req As HttpWebRequest = WebRequest.CreateHttp("https://example.com/check?email=" & email & "&pass=" & LCase(passHash))
req.Method = "POST"
req.ContentType = "none"
req.ContentLength = 0
req.KeepAlive = True
req.CookieContainer = New CookieContainer()
req.UserAgent = "Test"
req.Accept = "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
req.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US;q=0.9,en;q=0.5")
req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8")
req.Headers.Add(HttpRequestHeader.CacheControl, "no-cache")
Dim statusCode As HttpStatusCode = Nothing
Try
Using result As HttpWebResponse = CType(Await req.GetResponseAsync(), HttpWebResponse)
statusCode = result.StatusCode
End Using
If statusCode = HttpStatusCode.OK Then
MsgBox("Valid")
Else
Dim response As String = New StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd()
MsgBox(response)
End If
Catch webEx As WebException
MsgBox(New StreamReader(webEx.Response.GetResponseStream()).ReadToEnd())
End Try

Restsharp :The SSL connection could not be established

An app is run on netcore2.1.5,win7.
I use restsharp to request the API and need to take client certificates, always return the error:
The SSL connection could not be established, see inner exception.
Authentication failed, see inner exception
The inner exception content:
System.ComponentModel.Win32Exception (0x80090326): 接收到的消息异常,或格式不正确。
English version:
"The message received is abnormal or not formatted correctly"
I user postman to request the API and take the same crt file and response the
result result.
My code on below:
string clientCertfile = #"E:\https\client.crt";
var client = new RestClient("https://apiserver/iocm/app/sec/v1.1.0/login");
X509Certificate2 certificates = new X509Certificate2(clientCertfile);
//X509Certificate2 certificates = GetMyX509Certificate(clientCertfile);
client.ClientCertificates = new X509Certificate2Collection(){ certificates };
client.RemoteCertificateValidationCallback =
new RemoteCertificateValidationCallback(OnRemoteCertificateValidationCallback);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("appId", "rIsyJsnMtOrKfpSO90");
request.AddParameter("secret", "8v0fH0ztunjP1oXT");
IRestResponse response = client.Execute(request);
postman test image

Cannot load page with either WebClient or HttpWebRequest

Regardless of whether I use WebClient or HttpWebRequest, loading this page times out. What am I doing wrong? It can't be https, since other https sites load just fine.
Below is my latest attempt, which adds all headers that I see in Firefox's inspector.
One interesting behavior is that I cannot monitor this with Fiddler, because everything works properly when Fiddler is running.
Using client As WebClient = New WebClient()
client.Headers(HttpRequestHeader.Accept) = "text/html, image/png, image/jpeg, image/gif, */*;q=0.1"
client.Headers(HttpRequestHeader.UserAgent) = "Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12"
client.Headers(HttpRequestHeader.AcceptLanguage) = "en-US;en;q=0.5"
client.Headers(HttpRequestHeader.AcceptEncoding) = "gzip, deflate, br"
client.Headers(HttpRequestHeader.Referer) = "http://www.torontohydro.com/sites/electricsystem/Pages/foryourhome.aspx"
client.Headers("DNT") = "1"
client.Headers(HttpRequestHeader.KeepAlive) = "keep-alive"
client.Headers(HttpRequestHeader.Upgrade) = "1"
client.Headers(HttpRequestHeader.CacheControl) = "max-age=0"
Dim x = New Uri("https://css.torontohydro.com/")
Dim data as string = client.DownloadString(x)
End Using
All of this is excess code. Boiling it down to just a couple of lines causes the same hang.
Using client as WebClient = New WebClient()
Dim data as string = client.DownloadString("https://css.torontohydro.com")
End Using
And this is the HttpWebRequest code, in a nutshell, which also hangs getting the response.
Dim getRequest As HttpWebRequest = CreateWebRequest("https://css.torontohydro.com/")
getRequest.CachePolicy = New Cache.RequestCachePolicy(Cache.RequestCacheLevel.BypassCache)
Using webResponse As HttpWebResponse = CType(getRequest.GetResponse(), HttpWebResponse)
'no need for any more code, since the above line is where things hang
So this ended up being due to the project still being in .NET 3.5. .NET was trying to load the site, being https, using SSL. Adding this line fixed the problem:
ServicePointManager.SecurityProtocol = 3072
I had to use 3072 since 3.5 does not contain a definition for SecurityProtocolType.Tls12.

FTPWebRequest.GetResponse timeout on server, not on local debug

I made a Azure cloud service which download files from a FTP server and then upload them to an Azure storage.
When I debug my service, everything works fine, the files are uploaded to the storage. Once I published the service, I received an error (not always, but 4 times of 5 try):
"System.Net.WebException: The operation has timed out."
The line number of the error correspond to the line
Dim response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
Why does it work on local debug and not from cloud ?
For information, there is no proxy or what. It seems to work in a random way.
A part of my code :
'Request
Dim request As FtpWebRequest = CType(WebRequest.Create(Configuration.Address + suffixPath), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.DownloadFile
'Login and pwd
request.Credentials = New NetworkCredential(Configuration.Login, Configuration.Password)
request.UsePassive = False
request.KeepAlive = True
request.Timeout = Integer.MaxValue
request.ReadWriteTimeout = Integer.MaxValue
Try
Dim response As FtpWebResponse = CType(request.GetResponse, FtpWebResponse)
Dim stream As Stream = response.GetResponseStream
...
Thx all
--- EDIT ----
I found this article :
http://feedback.azure.com/forums/217313-networking-dns-traffic-manager-vpn-vnet/suggestions/3346609-icmp-support-for-azure-websites-roles-cloud-serv
It's a suggestion to add ICMP traffic for Azure VMs, Services...
I tried to do a simple ping test from my Azure Cloud Service to my FTP Server, with a Timeout of 30 seconds, I received ... a timeout error immediatly.
Do you think guys that is a possible explanation of my problem ?
If it does, is there any means to download file from ftp by passing thru UDP or something else ?
I Finally found the solution to my problem.
The restriction for ICMP traffic inside a Azure VM or Service was the thing.
So, I simply used a WebClient object to download my files.
Dim webclient As New WebClient
webclient.Credentials = New NetworkCredential(login, password)
Dim bytesData As Byte() = webclient.DownloadData(addressOfFTPServer + fileNameToDownload)
Return bytesData
Hope this will help.

Basic Authentication Webpage Login VB.NET

Hey all, I am having an issue with trying to automate our UPS installations. The webpage uses basic authentication and prompts for a login when loading the page. We do not have access to the registry to enable this feature in IE since it was disabled. I have tried useing an httpwebrequest and response to pull the cookie but it doesn't ever appear to send one back. My logic for that was going to be to use that cookie for the web browser control so it wouldn't then ask for the login. Here is my code that I have for that:
Dim request As HttpWebRequest = DirectCast(WebRequest.Create("http://10.106.206.249"), HttpWebRequest)
Dim mycache = New CredentialCache()
mycache.Add(New Uri("http://10.106.206.249"), "Basic", New NetworkCredential("User", "Pass"))
request.Credentials = mycache
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
request.CookieContainer = New CookieContainer()
Dim response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
Dim cook As Cookie
For Each cook In response.Cookies
Console.WriteLine("Cookie:")
Console.WriteLine("{0} = {1}", cook.Name, cook.Value)
Console.WriteLine("Domain: {0}", cook.Domain)
Console.WriteLine("Path: {0}", cook.Path)
Console.WriteLine("Port: {0}", cook.Port)
Console.WriteLine("Secure: {0}", cook.Secure)
Console.WriteLine("When issued: {0}", cook.TimeStamp)
Console.WriteLine("Expires: {0} (expired? {1})", cook.Expires, cook.Expired)
Console.WriteLine("Don't save: {0}", cook.Discard)
Console.WriteLine("Comment: {0}", cook.Comment)
Console.WriteLine("Uri for comments: {0}", cook.CommentUri)
Console.WriteLine("Version: RFC {0}", IIf(cook.Version = 1, "2109", "2965"))
' Show the string representation of the cookie.
Console.WriteLine("String: {0}", cook.ToString())
Next cook
I know this works to some extent because if I use the incorrect creds I get an unathorized error thrown. So it appears either I am not catching the cookie or one is not being sent.
Another way I have tried is by sending a header with a regular Web.Navigate but that just acts like it is loading the page and prompts for login:
Dim authData
Dim authHeader As String
authData = System.Text.UnicodeEncoding.UTF8.GetBytes("User:Pass")
authHeader = "Authorization: Basic: " & System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("User:Pass")) & Chr(13) & Chr(10)
Web.Navigate("http://10.106.206.249", False, Nothing, authHeader)
Anyone have any insight to see if maybe I am just doing something wrong here?
A simpler solution would be this:
Web.Navigate("http://Administrator:retail#10.106.206.249")
Note that if you have an #-sign in your password you'll have to UrlEncode it. (I'm not 100% sure whether the password will still work then)