Socket authentication with SSL - c#

ANSWER: I'm using Mutual SSL Authentication. Now there isn't any problem :)
I'm working on a server project. I've tried authenticate client with a XOR encrypt-decypt method but this isn't secure enough. I decided to use SSL with my sockets but I can't do it. I've a System.Net.Sockets.Socket based connection. Namely I want this: if a Tcp connection is incoming, authenticate is it our client's socket connection. (every socket can't connect our server socket from our port). Can anybody give me a start point or some examples? (This is the dead point of my server. if I can't do it, it'll be cancelled!)
EDIT1: My system currently working like that:
Client connected to server.
Server created 16byte long random key and crypted it with serverKey (XOR), sent it to client
Client decrypted data with serverKey and crypted it with clientKey and sent it back
Server decrypted data and checked are there same
(When client connected, a timer started for auth timeout)
EDIT2: Now I'm using an other cryptology. When a client connected, it'll be sent and client will decrypt it and sends back. Cryptology working like this:
Encrypt byte[] with a special method (not professional). After, get a hash code of byte[]. This hash algoritm is written by me, and if anybody don't know it, never understand our encrypted byte[]. (already hash outputs can't came back). And finally it combines hash and crypted (like a XOR, a special method).
With this method, nobody gets decrypted/cracked data. Otherwise there is a asymmetric encrypt/decrypt method (http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange). I can upgrade my auth system with a (hard) asymmetrice cryptology later (if it isn't enough).

I think a good approach for you would be to use SSL with client certificates for authentication.
You would operate a Certificate Authority and issue a server cert for your server. You would also issue a client certificate for each client. Then in the server, you would restrict connections to only those that are signed by your CA.
This is a standard approach and should work with basically any SSL implementation. Is there a reason it's not acceptable for your situation?

The answer to your question is to use SSL with mutual authentication. You've tagged your question 'SSL' so presumably that's an admissible solution.
You will have to explain what you mean by "I can't do it".

I'm using Mutual SSL Authentication. It is best way to do it. (Sorry for other problems like "SSL not works with my systems")

Related

SQL Server TLS 1.2 communication really encrypted?

I'm writing a VB6 application which connects with SQL Server. To secure the connection with the database I'm using MSOLEDBSQL as provider which supports TLS 1.2. I also enabled TLS 1.2 in my machine. I verified the connection status using sys. dm_exec_connections and SQL server displays all the connections are encrypted. To double confirm I tried to use the echomirage to check the traffic and the results are surprising. The data is not encrypted and I can read all the data flow as shown in the below image. My question is
This communication is really encrypted. If not why I'm seeing different status in SQL server
I read somewhere that TCP is binary protocol. If so, why I'm seeing plain text even if this communication is not encrypted?
This isn't a TDS issue (the protocol used by SQL Server). The same thing happens with your browser when you use a debugging proxy like Fiddler and trust the proxy's certificate, or configure it to use a trusted certificate. Most likely, you trusted EchoMirage's certificate during setup or through its Settings and forgot about it.
SSL/TLS protect agains Man-In-The-Middle attacks by verifying the other party through certificates. Encryption isn't enough. Without verification a proxy between client and server could pose as the other party, set up encrypted communications with each side, decrypt the packets it receives, inspect them and then encrypt them again using the other side's keys and send them along. Without verification neither client nor server would know someone intercepted the connections.
With SSL/TLS, a connection is established only if both parties trust each other's certificates. Both sides verify the certificates by checking either whether the certificate is explicitly trusted, or if it was issued by a Certificate Authority trusted by the application. If validation fails, the connection fails as well.
Fiddler, WireShark and other similar tools decrypt traffic by acting like a proxy and establishing communications on either side using their certificate. With certificate validation enabled though, the browser (or the SQL Server client) would reject the connection. If you try to connect to a web site through HTTPS while Fiddler is in use you'd get a red warning page saying that the connection isn't safe.
To allow such connections someone would have to go and explicitly trust the tool's certificate. All tools can do this through their settings, but all OSs require privilege elevation and user confirmation before they add the certificate to their trusted list.
By default, drivers and network libraries perform validation. To allow WireShark to intercept the SQL Server connection you'd have to either explicitly disable validation with TrustServerCertificate=true;, or trust the tool's certificate, which is probably something you already did and forgotten about it.
The page Using Encryption Without Validation in SQL Server Native Client in the docs explains what happens when you don't use validation, and warns against it.
If you use Encrypt=true and leave TrustServerCertificate to its default, false, WireShark or EchoMirage won't be able to intercept, much less decrypt the traffic. In this case :
Encryption occurs only if there is a verifiable server certificate, otherwise the connection attempt fails.
This is a TDS issue (the protocol used by SQL Server), and is not caused by WireShark in any way.
TLS encryption is only used during the login process to ensure that the credentials are not passed unencrypted over the network.
After that, the remaining bulk-transfer of queries and result sets are not encrypted on the wire.
In order to enable encryption for data (and not just for the login process), you need to use the Use Encryption for Data connection string keyword in your connection string:
Use Encryption for Data=true
Use Encryption for Data
SSPROP_INIT_ENCRYPT
"Specifies whether data should be encrypted before sending it over the network. Possible values are "true" and "false". The default value is "false"."
Be aware: If you enable encryption for data, and the server doesn't have a valid certificate (i.e. the default), then you will get an error when connecting. The client will detect the server presented an invalid certificate, and stop the connection. In order to make your system reliable, you need to include Trust Server Certificate=true in your connection string:
Use Encryption for Data=true;Trust Server Certificate=true
A better alternative is to turn on the option on the server that forces encryption for data, and do not specify Use Encryption for Data or Trust Server Certificate in your connection string.
When it is the server that requires the encryption, the client will not care about the certificate presented by the server (excluding MSOLEDBSQL19, which is broken by default, and you will need to specify Trust Server Certificate=true even when it was the server who wanted the encryption in the first place.

Verify authenticity of an client

I have the following concern about security in server-client models...
Imagine the following:
I have an C# WinForms client that wants to communicate with a server (PHP GET-POST Requests, Socket or WebSocket in a Console App C# (Net Framework) running on a Debian under Mono, instead of using ASP.NET).
The first problem that arises is that whether the server (written in PHP or C #) must have some kind of control for the anonymous requests that the client generates, for this, we will have to use some type of token generated by the server to every request.
The problem isn't related to the token (my plan is to use HTTPS (PHP) or SSL / TLS + Certificates in WebSockets (C#) for client-server communications at the network level, to avoid Spoofing or MitM).
The problem arises when the server has to give to a "client" (we need to check its validity, that the main concern) a token to allow the client do requests. It would be very easy to any client to give a token from the server (How? Replicating (inverse ingeenering) a client that makes requests to the server to try to obtain valid tokens, at least, as I plan to implement it, hence the need for help).
In what I was thinking, is to generate a md5 or sha hash for the assembly file of the client. So, if anyone tries to replicate those steps, it will be difficult. Because he/she will need to modify the source code of the assembly or make a malicious assembly and obtain the same hash by collision (this is difficult).
I do not know how efficient is this system, so I need you to guide me a bit in this aspect.
I've been looking at OAuth, and I think that this type of implementation is not the one I'm looking for, because this kind of implementations is for the user level (to avoid that another user violates the main user data), not for the client (application).
So if someone can guide on this issue it would be of great help.
You can't authenticate the client, it is not possible. Anything in the client is known to the user (attacker), any secret, anything you have there. The only question is difficulty, but anything you do, it will not be very difficult.
Also in your hashing scheme, what would you do with the hash, send it to the server? Why would a different client have to match the hash, when it can send whatever it wants (ie. the correct hash, as sniffed from the network)?
So again, because the software needs to run on the client machine, anything that runs there or is sent on the network is disclosed to the user, and he can replicate it in a different client. It is not possible to securely prevent this. Also ssl/tls doesn't help here, if you control one of the endpoints (ie.the client).
Imagine if it was possible somehow, software piracy would not be a thing - but it very much is.

How to ignore signature hash algorithm requested by server during TLS1.2 handshake?

I have a C# application making a successful TCP TLS 1.0 connection with mutual authentication to another company's server. It is implemented using SslStream class. We are just one of many clients of this very large organisation.
This TCP link above must undergo TLS 1.2 + SHA2 upgrade. After doing all necessary steps on our side and successful testing with our local servers we are still failing all attempts to connect to the remote server. A lengthy investigation revealed that during TLS Handshake the server is sending to us a certificate request with only option for Signature Hash Algorithm = SHA1-RSA (see picture below). Our cerificate is SHA256. As a result, SslStream is not sending our certificate to the server at all and the server sees this as a Handshake Failure and closes down the connection.
The reason for this nuisance is that our counterparty uses very old (10.x) version of F5 firewall to terminate SSL. It only sends SHA1/RSA Signature Hash Algorithm in the certificate request although it supports the client’s SHA2 certificates.
While admitting the facts above, our counterparty is unable to upgrade F5 soon enough. They suggested to ignore the requested Signature Hash Algorithm and send our SHA256 certificate anyway. Apparently other clients connecting to them were able to do that somehow.
Unfortunately,.Net's SslStream does not provide that level of fine tuning for TLS handshake.
Hence the question: is it possible to ignore the server's request for SHA1RSA-based certificate at all? What options do I have? Are there SslStream alternatives that implement TLS 1.2? Is there an open-source third-party solution? Any suggestion would be helpful. Thanks in advance.
The issue above was eventually resolved without any special code changes: a proxy server added on our side. It took care of communication with the other party. The proxy server is able to ignore the specific SHA1/RSA Signature Hash Algorithm in the incoming certificate request.

How Secure is connecting to an SSL encrypted Website?

I am using WebClient to implement a secure account check before a customer can use my application. but what I am worrying about is "does connecting to a website that uses SSL Certificate using HTTPS protocol prevent MATM attack and makes the whole communication encrypted ?".
In another words: will some programs like Wireshark be able to get the requests and responses in plain text as with using normal HTTP requests ? and is there an ability to alter the sent and received packets ? in order to change my application behavior or something.
[NOTE] I am not talking about getting my application pirated as I know that there is no way to get away from that fate.
HTTPS does prevent Man in the middle attack, as long as both sides are implementing the protocol properly and I assume that WebClient is implemented properly.
That means that even wireshark that is installed on your local box won't be able to decrypt the traffic
If someone in the middle would alter packets on their way, the other side won't be able to read them and the communication would break.
Some clarification given our discussion in your comments:
The above holds if your client is not compromised (HTTPS does work), since you are assuming that your clients will compromise themselves and use tools that will cheat your application by adding fake trusted certificates (which requires admin rights), I can suggest you to use two way ssl.
The tools that I know like Fiddler won't be able to decrypt this just by adding their trusted certificates, thus making it more difficult for your clients to attack your application this way, and bring them to use a debugger or patch it, because it is easier than implementing a two way ssl proxy.
You can also do what's described in this post to override the framework's certificate verification with code that expects one specific certificate and ignores the system's trusted certificates, which is compromised by tools like Fiddler (this implements What Mark suggested).
HTTPS encrypts the transmitted data and prevents man in the middle attacks by authenticating the HOST you are connecting to. However, in regards to a desktop application and also a web application, the user can use wireshark or an http proxy to view the contents of the https transmissions on the local host.
A way to mitigate this problem is to hard code the thumb print of your server cert so that you r application can encure that the server it's connecting to is presenting a specific certificate.
An example, would be if you were to install Fiddler on your local box and install the fiddler root certificate. Your application would think it's securely connecting to the server, but fiddler would be in the middle decrypting traffic. If your application code looks for a specific certificate thumbprint, you can throw an exception when a certificate other than the certificate you expect is used to connect, thus preventing the transmission of any data when a local proxy is in use.
Wireshark will always be able to see the packets being transmitted over the network but you won't necessarily be able to see the contents of the transmission unencrypted. However I'm not an expert in using Wireshark, so maybe someone else here can expound on that.
UPDATE
Ok to clarify more.... this question is discussing the encryption of contents being sent from a desktop application to a server.
Let's layout some assumptions:
The user of the desktop application, controls their desktop.
The application installed on the desktop is using a public key to encrypt.
Anyone with the corresponding private key can decrypt.
Since the user controls their desktop they can also run an http proxy on their desktop.
Now the way SSL(HTTPS) works is that your browser starts a secure handshake, at which point the server will return the public certificate, and your browser will attempt to authenticate that certificate with the authority you puchased the certificate from like (godaddy, geotrust, or versign, etc)
Assuming the user installed fiddler and it's root certificate, your desktop application would connect to fiddler, and be served fiddlers public root certificate, which it would validate against the locally certificate store and deem it trusted. Fiddler would then contact the server, which would send it the real public certificate.
Subsequently your http request from the browser is encrypted by the browser using the fiddler root public key, fiddler then decrypts the contents, and then reencrypts it using the public key from your server (mydomain.com) and forwards the request to the server, which then decrypts it and processes it.
Here is more information: http://en.wikipedia.org/wiki/HTTP_Secure
SSL offloading(https://f5.com/glossary/ssl-offloading) is also a feature used in network infrastructure for offloading the SSL load on other devices than web services. This is a form of man in the middle decryption of content. Also, Instrustion Detection systems in enterprise networks can have SSL certificates installed in them allowing these devices to decrypt the contents of requests and inspect them for behaviors indicative of network attacks.

Two-way authentication for SSL communication

I am trying to send information (in the form of an mime file) to a third party host server that uses two way authentication. After much coaxing I got enough information from their non technical help desk staff to figure out that it is most likely a type of TLS/SSL communication. They use client and server handshakes. I found the following example:
sslstream example. But am having problems using it (TcpClient refuses to see the host adddress).
Before I get too far I was hoping some one could point me in the direction of some good examples or more information on this process. I'm feeling pretty lost.
By two way authentication, probably they mean that they require a client certificate. This means that during the handshake, the client side has to present a certificate to the server as well. The most common SSL behavior is that only the server part presents a certificate, such as when you go to a normal site that is using HTTPS.
As for SslStream, it is quite straightforward to use. To be able to present a client certificate, you need to have a certificate in the certificate store or a pfx file that you can load into memory during runtime.
I found this sample which seems good enough. Here is another one. The second one doesn't use client certs, but you can add them as a parameter to the the AuthenticateAsClient call.
If the TcpClient is refusing to see the host address, then this is most likely some kind of connectivity issue and not related to the actual SSL implementation.

Categories

Resources