I receive a CommunicationException on any port other than 443 - c#

I have a standard n-tier application (.Net 4.7.2) with a console server and a WinForms application both running on the same machine. The client and server communicate via WCF.
I get a CommunicationException on the client when I attempt to communicate with the server if I use any port other than 443 in my address binding. not specifying a port or explicitly specifying 443 works without an issue.
The error message is;
An error occurred while making the HTTP request to
https://localhost:44333/SecurityTokenService/issue/wstrust/mixed/anonymous.
This could be due to the fact that the server certificate is not
configured properly with HTTP.SYS in the HTTPS case. This could also
be caused by a mismatch of the security binding between the client and
the server.
here is my client binding for reference
<endpoint
address="https://localhost:44333/SecurityTokenService/issue/wstrust/mixed/anonymous"
binding="customBinding"
bindingConfiguration="MySecurityTokenEndpointBinding"
contract="System.ServiceModel.Security.IWSTrustChannelContract"
name="SecretTokenAuthenticationEndPoint" />
UPDATE: I have continued to investigate the issue myself and enabled WCF tracing. I can see from the trace logs the warning 'The Security Protocol cannot secure the outgoing message'

Make sure to use the correct way to call the wcf service, such as adding service reference, channel factory, etc. After reading your question, I think it is very likely as the error message says: 'This could also be caused by a mismatch of the security binding between the client and the server.'
You can use the following code to specify the TLS version:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
TLS1.3 is the latest TLS standard protocol, which is faster and has higher security.
Here is the reference: Transport Layer Security (TLS) best practices with the .NET Framework

The solution for me was to bind the SSL certificate to the IP Address and Port that my service was being exposed on. I used the following command from a command prompt;
netsh http add sslcert ipport={ipAddress}:{port} certhash={CertificateThumbprint} appid={appId}
Some points to note
If the above command fails; ensure you have the private key imported and not just the public certificate
I don't know if the appId is an arbitrary Guid; I used the Guid from my application shell project (a console application); It's the Guid that exposes your application to 'com'
Hopefully, this helps somebody in the future

Related

How to connect to remote gRPC service

I created a gRPC service and client in C# .NET Core 3.1. When I deploy the service to localhost, I can connect to it without a problem. But when I publish the service to a IIS via WebDeploy and start it there I cannot connect to it.
For a local deployment, the channel is initialized as follows:
var channel = GrpcChannel.ForAddress("https://localhost:5001");
For the remote deployment I change it to the following value, since it starts as a HTTP service on http://localhost:5000 on the remote machine (which I also failed to find out how to change - I would prefer it to start as a HTTPS service):
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var channel = GrpcChannel.ForAddress("http://1.2.3.4:5000");
1.2.3.4 is the IP of the remote machine, which I am able to ping. I also created a firewall rule to allow all inbound traffic on inbound port 5000.
The client application fails on the first remote call with the error message
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I fail to understand which measures I have to take to create a connection to the remote service. All example gRPC code I have found so far uses localhost as a deploy point and did not help me figure out the root cause of my problem.
Any help or pointers towards what I must have missed are appreciated.
From Tutorial: Create a gRPC client and server in ASP.NET Core, a warning almost at the end of the article, says
ASP.NET Core gRPC is not currently supported on Azure App Service or IIS. The HTTP/2 implementation of Http.Sys does not support HTTP response trailing headers which gRPC relies on...
Please refer to gRPC in production for ways to run your gRPC service in production.

Cannot consume SOAP endpoint with .NET WCF but testing endpoint with SoapUI works

I am currently developing a .NET client (with WCF) that must consume a third-party SOAP endpoint. This third-party endpoint requires HTTPS. When I test the endpoint with SoapUI, the endpoint responds correctly. However, when I try to consume the endpoint with the .NET client, I get the following exception:
System.ServiceModel.CommunicationException: An error occurred while making the HTTP request This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.
The inner exception was:
Unable to read data from the transport connection : An existing connection was forcibly closed by the remote host
The only solution I found was to use a newer version of TLS but this did not solve the issue.

Issue with Xamarin App Connecting to WCF Service over https

I am developing an Xmarain.Forms app to initially work on Android along with a service it will be connecting to. The service is a WCF service and needs to use a secure transport to send messages so is set to use https.
I can correctly connect and use the service with both SoapUI and a console program built using the same client proxy library but when I try using the Xamarin App it fails. When run in the emulator the exception is a TimeoutException but when installed on an actual device the exception is WebException with message of "Error: SecureChannelFailure (The authentication or decryption has failed" with inner exception stack of:
IOException with message "The authentication or decryption has failed"
IOException with message "Error while sending TLS Alert (Fatal:InternalError)"
IOException with message "The authentication or decryption has failed.
IOException with message "Unable to read data from the transport connection: Connection reset by peer"
The full stack trace is included below as attachments. The full code is available at https://github.com/staircase27/WcfXamarinHttpBugExample along with the instructions of how to set it up and use it. The example code has connections using both http and https to show the difference and to show that one works and the other doesn't. I have also checked while testing that the devices can access the service using their web browsers so it's not a firewall or routing issue.
I have also wiresharked the connection to see where exactly the connection is failing and it's failing at the TLS v1.0 level. The app (on both devices I've tested) is sending a Client Hello and the service is responding with a TCP RST packet rather than a Server Hello. I have also performed a connection from the testing device using a web browser that succeeded and the main differences are in the types of encryption supported specifically the app only offers to use
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_DES_CBC_SHA
where as the working connections both used
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
A filtered wireshark with two connections is at https://github.com/staircase27/WcfXamarinHttpBugExample/raw/master/Mobile%20WCF%20https%20Capture%20-%20Filtered.pcapng. The first connection is from the app and fails with a tcp rst. The second is the start of the connection from the android web browser.
I have enabled all versions of TLS and all cypher suites but it hasn't changed the wireshark trace or exception in the app.
I have also checked the SChannel Event Logs as recommended by #tomasr and found the following event:
An SSL client handshake completed successfully. The negotiated cryptographic parameters are as follows. Protocol: TLS 1.0. CipherSuite: 0xc014. Exchange strength: 256
(Before enabling all version of TLS the events were:
An TLS 1.0 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.
The following fatal alert was generated: 40. The internal error state is 1205.
)
Sadly as none of the suggestions in the comments worked I have had to work around this and am now using a RESTful WCF API and have implemented the client manually using HttpClient.

WCF service (self-hosted) over HTTPS - Get negotiated SSL/TLS protocol version

Due to security reasons, we wanted to disable TLS 1.0 support in our server on OS level (in followign SChannel registry):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
But because the SQL Server service won't start with TLS 1.0 disabled, we had to leave the TLS 1.0 enabled on OS level.
What we are trying to do now is to force the usage of TLS 1.2 on application level rather than on OS level.
Our application is Client-Server, running on .NET 4.5.
On the Client, before calling the WCF service, we set:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
That ensures that the Client will send ClientHello message with TLS1.2 protocol.
But on the Server, which is self-hosted WCF service, we do not see how to force the TLS1.2 usage. The SSL/TSL negotiation on the Server side is based on the SChannel registry and thus setting the ServicePointManager.SecurityProtocol does not make any effect.
We would like to inspect the incoming WCF call in our Server code and check what TLS protocol used for the call, and close the connection if it is anything less than TLS1.2.
Is there any way how to get the incoming WCF call SSL/TLS protocol version? Something like HttpContext.WebSocketNegotiatedProtocol?
Have you tried using a custom binding with sslStreamSecurity?
<sslStreamSecurity requireClientCertificate="false" sslProtocols="Tls12" />

WCF SetCertificate: how is it used

I hava a self-hosted wcf service which is configured for ssl.
The certifiacate is bound to the port of the service by commandline,
using the 'netsh' command, e.g.:
netsh http add sslcert ipport=0.0.0.0:8000 certhash=XYZ appid={"ABC"}
This is described here:
http://msdn.microsoft.com/de-de/library/ms733791(v=vs.110).aspx.
It works as expeced.
Now I just discovered that there is a SetCertificate-Method:
http://msdn.microsoft.com/de-de/library/system.servicemodel.description.servicecredentials.servicecertificate(v=vs.110).aspx
So, I thought I can make use of this method, and do not need the netsh comamnd
for binding the certifiacte anymore.
But it does not work? SetCertificate seems to have no effect?
So what else is it used for?
Am I missing something?
I think I can answer my own question. Found the answer here:
http://msdn.microsoft.com/de-de/library/ms789011(v=vs.110).aspx
If the transport is HTTP (using the WSHttpBinding), SSL over HTTP provides the transport-level security. In that case, you must configure the computer hosting the service with an SSL certificate bound to a port, as shown later in this topic.
If the transport is TCP (using the NetTcpBinding), by default the transport-level security provided is Windows security, or SSL over TCP. When using SSL over TCP, you must specify the certificate using the SetCertificate method, as shown later in this topic.
So the SetCertificate method is only used when Transport is TCP. In my case it is Http, so I have to bind the Certificate to the port manually as I did.

Categories

Resources