Recently, We developed an application that we want it's users to pay for a monthly subscription in order to use it. So the first thing that came to our minds how to implement a secure way for our application to check for the User validity and those ideas came up
Using WebClient to enter to our website and Login using the user
provided credentials : However, this might be vulnerable to MITM
attack.
Using the first approach but using SSL certificate (to make sure
that we are connecting to our server and not the attackers') :
However, Fiddler can easily do a MITM attack and decrypt the SSL
communication, which will result in the same vulnerability as the
first approach.
Due to the internet's lack of documentation of what we need, we had to ask here for someone to explain how could we make sure that:
Our application only connects to our server and not any fake hosted
server (by the attacker).
The communication is secure. Not altered or edited some how in order to
grand unfair access to our application. (by sending a fake response
to the app or editing the original response before the application receives it).
Note: we totally understand that the attacker may just deobfuscate the application and do whatever he want to it. So we are planning to get a goodobfuscatorin order to at least make it harder for the attacker to do so.
You can use SSL Certificate Pinning.
Set the ServerCertificateValidationCallback to only accept your certificate's public key, or one of its signers. (this means you can never change certificates)
This will completely prevent SSL MITM (which works by using a different certificate and making the computer trust it).
Of course, it doesn't prevent attackers from cracking open your app and bypassing the check altogether, especially if you store local state.
Related
I have a Client & Server application set, both written in C# but some client versions might be distributed in other languages in the future. I want to protect my applications.
I was looking for some kind of advice to stop just random people sending messages to a server and acting like a client, what kind of validation can I put in place?
My client applications I distribute will be obfuscated but is this enough? I'm just looking for some advice in this situation, is it wise for me to add some kind of encryption other than SSL, or am I just being over protective and over curious? Any input is welcomed & accepted.
It is impossible to determine if you are communicating remotely with "your client" or another piece of software that also knows how to communicate in the way that your client does.
What you can do is ensure that you are communicating with someone that is authorized to communicate with you by using client certificates for your SSL session.
The server proves who it is to the client and the client proves who it is to your server. The security then rests in whoever holds the private key to the client certificate (and the password for this key file).
The C# SslStream Class has support for this. Namely the AuthenticateAsClient method is relevant here.
In summary, if your software is only secure when communicating with a client you wrote, then your software isn't secure period. Instead, design your server in such a way that you can serve client requests securely. Using authentication is one of these ways.
You would want to do two things....one is look up certificate pinning. Your app will validate your SSL cert to thwart man in the middle attacks and it makes it hard to circumvent. The other is when making requests to the server have some type of user name / password block on the server side script before the server side does anything so the requests will simply be discarded by the server if they are from an unknown source.
I'm writing a client/server application that requires the server needs to be able to authenticate the client and also requires all comms to be encrypted.
The mechanism to provide this needs to be self contained within the server and client application and also to be fully automated (no human interaction required). SSL seems to be the best way to do this and is also something I am familiar with using.
For each client that needs the client software deploying to it, I planned to create (on the fly) an MSI installer with the application, the clients certificate (signed by the server) and private key and the servers public certificate (so the clients can authenticate the server - the server certificate could be self signed).
I can generate the key for the client and make a CSR, but don't seem to be able to find a way of actually signing the CSR and generating a certificate for the client thou. I have looked into the Win32 Crypto API, but haven't managed to find any examples of how to actually sign a CSR and get a client certificate.
I know how to do all of this from the command line with the openssl tool, but am not sure of how to do it from within an application.
Please note that making system calls out to the openssl tool and passing in the parameters I know to work is not an option as it's a huge security risk to rely on the openssl tool not being compromised in any way. Doing it this way wouldn't for fill the self contained requirement.
I am going about this the right way, or is there a better way to achieve the same thing - basically authentication of the clients connecting to the server and a way of the connecting client to authenticate the server they connect to, all encrypted.
I cannot make any assumptions about the server (or clients) having a static IP or hostname (DNS can be broken anyways), nor can I make any assumptions about any existing PKI infrastructure.
I am writing this primarily in C#.Net, but would consider writing a C++ extension to this if it gives me this functionality.
Finally this is my first post here, so if I've missed out something obvious or have been short on any details, please ask and I'll fill in the gaps :)
Thanks,
James
In C# you can use PKIBlackbox package of our SecureBlackbox product which provides all the functionality you are looking for in .NET. Maybe BouncyCastle library also includes this functionality.
You need to rethink at least part of this. What you are doing is radically insecure. The client's private key needs to be generated at the client. Otherwise it isn't private, so it cannot possibly satisfy any of the tenets of PKI,. including the purpose for which you are issuing it. You lose uniqueness and you also lose non-repudiability. These are both fatal flaws.
I am about to start on a project that will be running as a windows service listening for incoming connections and doing some things locally then sending a reply message. I understand the basic concepts with sockets and communicating over the network, however the things the service are doing could very easily abused. I would like to authenticate the person connecting, preferably against the windows local users on the machine the service is running, to see if they have windows administrative/power user rights.
I know how to do it check the rights once I have their information but I know sending the user name and password to the application over the network in the clear is a no no. I was thinking of just encrypting the password with some secret key but I know "trying to be clever" is the worst possible thing you can do in cryptography so I wanted to know what is the "correct" way to handle this situation.
My second idea was just create a shared self signed certificate between the client and the server and just use TLS for the entire connection.
I may as well post what I was thinking of doing, if it is the right thing to do say so in the comments.
Both the client and server will have a PSK at run-time the server will send a random number to the client. the client will encrypt the credentials with the PSK and the random number as the IV. It will send back the encrypted blob plus whatever commands it needs done.
I am not concerned about replay or mitm attacks. I just want to authenticate the user and not have peoples passwords blasted all over the network.
Scott,
this may be a bit overkill and a bit off topic, but have you considered using a web service interface to serve your clients (instead of using raw sockets)?
ASP .Net web service interfaces are easy to implement, and in the end, you'll end up with a very well defined interface. They also have support for authentication and secure communication.
ASP .Net Web Service Tutorial
HTTP Security and ASP.NET Web Services
We're considering creating a program which sends a POST request to a server-side program for some processing. We'd like to consider some sort of verification to make sure the POST request isn't a random spammer attempting to overwhelm our system or something. I don't know too much about this stuff, but I was thinking the client might send a date-num and an "encrypted" date-num (not securely encrypted, just using some special algorithm). The server would then both encrypt the date-num AND decrypt the client-encrypted date-num. If either the encrypted date-nums or the decrypted date-nums didn't match, obviously it wasn't a request from our client, so the server will not act on the request.
As I said, I don't know that much about this. Am I going about it the right way? Is there a better way? If this is an ok way, whereabouts might I go looking for "encryption" algorithms? (most of the algorithms I find are for secure-encryption and can only be decrypted on the same machine. I don't care that much about security--I just am looking for verification).
Thanks a bunch for your help.
PS I'm not sure if this is a duplicate, because I didn't really know what to search. I couldn't find any other questions about this, but that doesn't mean anything.
EDIT:
To clarify, the server code should be as "drop-in" as possible -- e.g. if it can be done using straight PHP or ASP.NET rather than mucking around with server configurations, then that would be better. Same on the client end. Keep in mind this does not have to be secure, we're just attempting to keep spammers from POSTing random data a million times.
You could use ssl and client certificates and let the webserver handle it transparently. This way both the server and the client can be (more or less) sure about whom they are talking to.
What will your webserver be? IIS, Apache, ... ?
If it's an apache take a look at httpd 2.2 docs, Client Authentication and Access Control.
If it's an IIS see Enabling Client Certificates in IIS 6.0 (IIS 6.0)
Try using a cryptographic nonce.
On the page from which the POST is launched, a random number is generated and stored in the database with the requesting IP address and an expiry time (15-30 minutes?).
The same random number is stored as a POST variable.
On POST, in order for the processing to occur, there must be a successful lookup matching the nonce and IP address before the expiry time.
Combined with a honeypot captcha, it should do a good job of preventing bots from straining your system.
The usual approach for a problem like this is the inclusion of an HMAC. It allows integrity checking and sender authentication by the use of a secret key.
Scenario:
A publically available Web Service that I have full control over.
But I only want this specific desktop application (my published application) to have access to the Web Service.
I could store a secret password in the desktop client, but that would be easy to crack.
Is there any known implementation that enforces this?
PKI, assymmetric keys?
If the public will have access to copies of this Desktop App, any good reverser will be able to crack it and "imitate" its transactions with the server. It doens't matter how secure is your cryptography, everything you app needs to encrypt/decrypt data is included in the binaries, so the cracker only needs to dig it out of it.
The objective of cryptography is to protect data while it is being transfered, from "middle-man" hackers, but if you have access to anyone of the peers, you can easily crack it.
Your server must never trust what comes from the client side.
[edit resuming]
Despite you cannot 100% guarantee a supposed client to your server is or isn't your App or some "emulator" made by thirdies, you can complicate things to them. Its a common practice in game anti-cheats to sometimes, randomly, make the client App a trick question like "whats the hash of your main.exe from offset A to offset B?" or "from now on packet type 0x07 swaps with packet type 0x5f". Once a fake is detected, server enter in a "silly mode", act malfunctional, and blacklist their IP/account to this mode for several hours so they cannot have sure of what their program is doing wrong.
If you detect someone is building an emulator, make them start all over again: jumble the packet type tables, cryptography tables, change some packet formats and force your clients to update. You won't see crackers bothering you for a while... LOL
WS-Security provides for X509 encryption.
Part of that implementation includes the possibility of only giving specific clients the generated public key. That way, only your selected clients can connect to the service.
The easiest way is message security using client and server certificates. The best way is to import the client certs in your server machines and hard code the client cert thumbprint in the app.config file. The other way is negotiation of certs which I haven't tried before.
If you are using IIS to host the service then client certificates using SSL is another option.
MSDN link on WCF Security.