Is this a common and well-regarded pattern?
Secondary Question: Best encryption standard for my context?
Context: I have a windows service which sends JSON data to a RESTFul Service. In that JSON Payload is authentication credentials (passhash and username), but I still must account for a registered user tampering with the other "data driven" parts of the payload.
My Solution: Encrypt the payload with a private/master key from within the source code, obfuscated the best I can. This will verify the client (unless the master key is broken).
EDIT: My service collects internet latency data. I do not want to collect hand-edited data values. I realize that with the volatile/everchanging nature of network performance/latency, a user could simply unplug their connection or bunker down theirs to the point that my client is not given enough bandwidth/resources to do it job. These are things that I cannot realistically account for with the knowledge and time that I have. However, I do think I can protect service from receiving hand-edited payloads.
First thing I want to do is clarify something in your expectations.
There are 2 aspects to the data that are important to you:
- Authentication - The data that was sent to you was sent from a authorized, unmodified, program
- Integrity - The Data that was sent to you was not modified in transit.
The Integrity problem is the easier one to solve, simply have your program use a SSL connection to the server. You don't even need to use a cert signed by one of the normal CA's, in fact it may be better that you don't! You could create a CA for your App, then sign the cert yourself that will be running on the webserver with that private CA. If you do that you can hard code the public key of your CA in to the program and only allow it to connect to servers who have certificates signed by your private CA. Doing this will help prevent someone setting up a MITM SSL Proxy (for example Fiddler) to edit the data while it is being transmitted.
Authentication is a bit of a harder problem to solve. You need to prevent fake clients or modified real clients from connecting to your server and sending fake data, and that is not a easy problem to solve. If your software is running on a device where the attacker can run arbitrary code, the problem is impossible to solve. The reason it is impossible is the user could attach a debugger and step through your code step by step and replicate your process. The the only way to "solve" it is running your program on something that does not allow the user to run anything and any software that does run must be vetted by a 3rd party first (like a un-jailbroken phone).
However you can "mitigate" the problem, you don't need to make it impossible, just hard enough that any malicious user would not find it worth the effort to overcome the obstacles you put in.
Some things you can do to make it harder on a an attacker:
- All message are signed using a secret key you do your damndest to hide.
- Use a code obfuscator on the code to make it harder to reverse engineer.
- Use client certificates in your SSL connection and have your server reject any connection that does not have them.
- Higher a consultant who is more experienced than you to make your code harder to reverse engineer.
There is much much more that can be done but that is what I came up with with just thinking for a few minutes.
So to boil this all down, if you are not too concerned, just use bog standard SSL, that will likely stop 75% of the tampering. If you are more concerned, use the custom CA trick to foil any SSL MITM attacks to maybe get you up to 80%. But if you want to get above that 80%, it gets exponentially harder to do, and at some point you need to stop and ask your self "Is the amount of time/effort/money I am putting in to stopping that one more person from sending me that bad data worth it? Or can I just live with 20 out of 100 people sending me bad data, what about 10, 5, 1?"
If the RESTFul service is your own, you could enable windows authentication on it (or deploy another instance of it with windows auth) and then authenticate the user, preferably that they belong to a role (or group). That way you've got no certificates or keys to mess with and it's secure.