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.
Related
I am trying o figure out how CoAP server handles authentication. DTLS seems to be the only option. However I could not find any clear example of it for .NET. I have also seen a mention about cookie on server side but that is all, no more information.
https://github.com/chkr1011/CoAPnet seems to be a good library. They also have a client example but I sould not find server example of it. Projest seems to have CoAP server as well, however I could not find it in source code.
Can any client send requests to the server if url is known? Is DTLS the way to go? Is there any server/client example of DTLS in C#?
If a java server will also help, have a look at eclipse/californium. We run a sondbox at "californium.eclipse.org" and if you want to "connect" a client, you may just use the "openssl" PSK demo credentials "Client_identity" and "secretPSK".
Can any client send requests to the server if url is known?
That depends on the protocol variant. Without encryption (plain coap), yes. Some projects then use a "token" in the request, to authenticate the request (see ThingsBoard). With encryption (DTLS, coaps), you need valid credentials, e.g. PSK (as above), a x.509 certificate or a Raw Public Key certificate. There are also setups, where only the server authenticates itself using x.509, and the client then uses the already encrpyted communication to authenticate with an other mechanism (e.g. username/password, so very similar to the model, mostly used with https).
The most pain is usually to find implementations, which could be used in the intended/wanted way. Maybe some projects helps you, to adapt the implementation.
Is DTLS the way to go?
In my opinion, yes. The alternative with OSCORE (payload encryption) are currently in development, we will see, if that changes the game.
Is there any server/client example of DTLS in C#?
I don't know that. Maybe you ask that the project you already found. Or ask here CoAP-CSharp
I made a FTP server application which uses Net's sockets. The application will immediately disconnect a client, that was accepted by the TcpListener, if the client didn't send a login message containing a username and password. But how do I prevent someone from decompiling my client application and seeing the server's password and replicating the message that's required by the client, to login in to the server, in another app. In general I want to avoid someone from making an application, that implements my objects from the .dll provided with the client application, which can connect to my FTP server.
There isn't really a way to completely protect your service if you are going to distribute a client library. As Kinetic says, hard coding passwords is definitely a bad idea because someone could easily decompile your assembly or use something like process explorer to discover it.
There is usually little harm in gracefully handling any client that conforms to your protocol. If you think that it's likely your service will be the subject of abuse then perhaps look into denial of service protection. 😉
I have been looking but cannot find a good answer that can help me in my case. To explain the situation, I am creating a Unity3D game which will have a multiplayer system. In order to keep the player data as secure as possible (so people doesn't cheat easily), I decided to implement a Web API 2 service that connects to a SQL Server database. I designed the Web service in such a way that only if the request contains specific data the request is processed. What I am now having problem is to design a solution that will let me send/retrieve data from the web service. I implemented SHA-512 to send the password so packet sniffers wouldn't get it in plain text, and I am planning to implement HTTPS but Unity classes makes it very hard. I thought of implementing RijdnaelManaged as a more secure algorithm for the accounts but in Unity the code is easily reverse-engineered.
Would this model be secure enough to stop script kiddies from hacking player accounts?
HTTPS
I implemented SHA-512 to send the password so packet sniffers wouldn't get it in plain text,
That's not helping for as far as your webservice goes, it now uses the hash as its password, so anybody sniffing it will still capture it.
Use https, not http to get it right.
If you really cannot: build a system where the service first issues a challenge, and where the client then "signs" that challenge and sends the signature back. That's still by far not as good as https, but it'll prevent a few things (but not e.g. a man-in-the-middle attack).
Security
If you look at analyzing the risks, you need to take care to address users of your game as well as 3rd parties.
The 3rd parties, with good passwords (good luck with that) or proper 2 factor authentication, https etc. you can cover the bases rather well. Add in some security in the webservices and you should be a good way along the path.
But you also have to deal with users of the game. And that's harder than it might seem as they could run your game in a debugger and figure out how the game communicates with the server and what it sends when, what the effects are of that etc. Nw if you have a multi-player game typically that involves virtual goods and/or currency that can be obtained and/or traded. Devious players will try to get it the easy way, so you need to protect somehow against that as well.
The easiest to do that is to move the game logic into the server and use the client only for visualizing things - but that obviously means you make much more use of server resources ...
Trusting your client is running, unmodified, and you're talking to it: you can't ...
I'm writing a C# .NET application that requires a secure Login. I've already got the necessary functionality to store passwords securely with a hash and salt in a database, however, I'm now moving from the testing phase. Before during development (the Login wasn't prioritized) I was just connecting to my database directly. I'm aware this is insecure for a production application as you blatantly store your database credentials in the code. Instead, I'm opting to create a simple Asynchronous TCP Socket server that listens for a username, sends the salt from the database back, then the client hashes the entered password (salt is stored locally temporarily) and sends that back to the server. The server then checks if they match; sends back true/false if the user checks out.
I've done some research and looked into encrypting the TCP Connection, however, is this really necessary, since the password will already be hashed? Or is there a better way of doing things in entirety? I'm open to suggestions on how the client/server architecture should work. The Login doesn't play that important of a role in the application as a whole, but it will be production grade and I do not want to put a poorly designed application out there.
then the client hashes the entered password (salt is stored locally temporarily) and sends that back to the server. The server then checks if they match; sends back true/false if the user checks out.
I've done some research and looked into encrypting the TCP Connection, however, is this really necessary, since the password will already be hashed?
It doesn't matter what you call a "password", the only thing that matters is what the server will accept as valid credentials. If you input a password and the server hashes it there (as #Christian Stewart suggested in the comments), then you password is your credential. If you salt and hash the password yourself, and send the result to the server, then this result will be your credential. Intercepting it is as good as intercepting the original password + salt.
So, yes, you must also encrypt your connection, before sending credentials through it. The SslStream Class, seems to be the easiest way to do that (check the example code at the bottom, both for server and client), and it supports both server authentication and optionally client authentication as well (in case you also want to restrict which machines will have access to the Login server).
1) If you are sending sensitive data, the easiest way to protect it is to use SSL. If this is an internal project, you can generate your own certificate. Also, talk to your IT staff about whether this is even a potential problem. If this is going to be deployed in a properly-configured wired intranet situation, users can't see each other's traffic.
2) Your use of salts and hashes is messed up and it no longer solves the problem that it's meant to. Hashing and salting is meant to render the contents of the database unhelpful for an attacker. That's not the case here, since what is stored in the database is what's accepted by the server as an authentication token. Hashing must be done on the server so that the value the server accepts over the wire is irreversibly (hash) and uniquely (salt) transformed into the value that appears in the user store. Now it's true that an attacked can't reverse it to get the user's password (i.e. what they type in to your client) - which is good - but an attacker doesn't need the password if they know the value in the database.
3) Put on your attacker hat. If you watched your authentication exchange take place, would you be able to log in without knowing the secret? Yes, you would just send the last thing the client sent. So this channel should be encrypted.
4) If you can avoid it, don't write your own crypto. Don't even manage users if you can avoid it. People don't want to manage users and groups in every application they use - and I say this as someone who's made this mistake before. Can you use LDAP or domain authentication or something?
There are ways to authenticate an user with the server without ever transmitting the password, using protocols such as the free SRP used by World of Warcraft.
SRP will perform a serie of challenges to authenticate the user based on what each party knows about the password, without ever leaking sensitive information about it to the network.
Still using WoW as reference, there are open source emulators for it such as TrinityCore that give you a solid exemple of SRP in action.
I know I cant prevent people from reverse-engineering my protocol but I'd like to take a security-through-obscurity approach to make it as hard as possible.
I have a server/client system that communicates through the network with http style packets.
Example:
Header
Attribute: Value
Attribute2: Other Value
Payload
I would like to make it as hard as possible for anything other than my client to access the network. Pushing problems with them decompiling my assemblies aside - what would be some good things I could do to this network spec that would make it VERY DIFFICULT to understand and make another implementation without the source?
I was thinking some kind of strange hashing approach or some kind of encryption algorithm that would be difficult.
EDIT I'm not trying to protect my assemblies or source-code. I'm trying to prevent someone from, for example, watching my protocol with WireShark or similar and then making their own implementation based on that information.
All right, three cases:
Users can't access server code and can't access client code: Easiest way is to use a pregenerated shared secret stored in the binary, and aes encrypt/decrypt.
Users can access client or server code but not both: Use a public/private key method. You can encrypt using the public key but the private one is needed to decrypt.
Users can access both client and server code: You're screwed.
If you want to improve security, this static key should only be used during session initiation, to generate a new shared secret, which is then used for communication.
Edit: actually, a more easy and safe solution is to use ssl and certificates (it's a mantra that you shouldn't implement your own encryption) Each certificate comes with a secret private key. As long as users don't have access to that you're safe if you verify that the peer has the exact correct certificate.
For having reversed a few network protocols (from MMOs), I can tell you that you will never protect your protocol for very long, I'm sorry.
The best you can do is:
Obfuscate it using a custom algorithm (because it takes longer to reverse than a known one). Using a known encryption scheme offers no protection whatsoever.
Add noise. Try to be very, very confusing. Add random values that make no sense whatsoever. Try to use a dynamic layout for packets. Move fields. Send useless packets. Just like if it were garbage.
Version your protocol, so that two consecutive version are incompatible. That can be hard to do, but it obliges the reverser to re-do the work for every subsequent version.
But these are just ways to slow down attackers. It's certainly not going to stop them.
There are three solutions:
TLS.
SSLv3.
Whatever you cook up.
1 and 2 already work.
I am also in the process of writing a network protocol in C#. I have made use of encryption to secure the protocol. Here is the outlay of how I did it, you might find this useful.
As soon as the client connects the server requests a random UUID from the client, the client encrypts this UUID with a password know to both the server and client.
All packets sent thereafter by the server or client will encrypted using that UUID as a key.
Regarding "I was thinking some kind of strange hashing approach", hashing is usually only used for data verification. i.e. to ensure it was not modified en-route to you.
Hope this helps.