1

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 Development WS

On Prod (srv 2016) there is "TCP Spurious Retransmission" after "Server Key Exchange" as on screenshot Production WS

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()
manuel
  • 1,840
  • 1
  • 16
  • 16
  • The following may be helpful: https://learn.microsoft.com/en-us/security/engineering/solving-tls1-problem and https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls – Tu deschizi eu inchid Jan 19 '22 at 19:50
  • I forget to mention that if I try this in postman everything is working just fine on WinSrv2016, so this is looking like .NET issue – manuel Jan 19 '22 at 21:21
  • Adding `ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12` **after** a request has been created is useless. -- See the sequence in [Which TLS version was negotiated?](https://stackoverflow.com/a/48675492/7444103) – Jimi Jan 19 '22 at 22:21
  • ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 is before request.GetRequestStream(), and yes I tried to move it before creating HttpWebRequest, same thing. – manuel Jan 20 '22 at 08:01
  • That property must be set before you create any object, i.e., before you create a WebRequest. Anyway, even though that's mandatory, you need to check the Client certificate available. Get [IIS Crypro](https://www.nartac.com/Products/IISCrypto) (free software), check what protocols are enabled, what Cipher Suites are installed and that all the relevant (newer) are enabled. SHA1 must be enabled, too. -- Windows Server 2016 should have all the necessary Cipher Suites, though, unless someone tampered with the Registry. – Jimi Jan 20 '22 at 09:30
  • See all the Cipher Suites available per Windows version in [Cipher Suites in TLS/SSL (Schannel SSP)](https://learn.microsoft.com/en-us/windows/win32/secauthn/cipher-suites-in-schannel) and make a comparison. -- The code in the Q&A I linked can be used to determine the SSL protocols exchanged, the result of the Certificates validation procedure and the related OIDs. – Jimi Jan 20 '22 at 09:38
  • Tried few things with IIS Crypto, 1. server protocols are TLS 1.0/1,1/12 and Client too Cypher Suits almost all are enabled (server was restarted), nothing changed – manuel Jan 20 '22 at 13:13
  • Works fine on WinSrv2016 when XML is sent through Postman (remote server ONLY uses TLS1.2) – manuel Jan 20 '22 at 13:18
  • Tried to remove with IIS Cypto 3.2 Client protocol to enable only TLS1.2 same thing, is there a way to get more info why TLS is failing ? – manuel Jan 20 '22 at 13:22
  • These are all *generic* suggestions that should put the code in a *predictable state*. You have duplicate ACK caused by *spurious retransmission*, so the network is is not correctly configured (wild DNS rountrips), there's a Proxy in between the sender and the receiver, the packets are sent from a network that has a much higher speed than the network where the receiver is located etc .(see also [Bufferbloat](https://en.wikipedia.org/wiki/Bufferbloat)). -- See whether there's some significant difference when you use one Server or the other. – Jimi Jan 20 '22 at 14:45
  • "obt2b1.service.com" is resolved to 10.101.220.11 (no problem with DNS) . Since you mention proxy I start "netsh winhttp show proxy" which shows: "Direct access (no proxy server)." WireShark shows that TLS is started on 10.101.220.11. Proxy argument makes sense but Postman is not using it and proxy is not set in vb.net is there a way to force direct connection in vb.net ? – manuel Jan 21 '22 at 09:15

1 Answers1

1

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 ...

enter image description here

After that I start IIS Crypto 3.2 set all setting to restrictive as it was before

manuel
  • 1,840
  • 1
  • 16
  • 16