Reputation: 31831
My Windows 8 (Metro) application uses different web services to access and mash up data. Each of those services requires a key (some multiple keys) to access them. As a result, these keys are valuable, and cost me money (or can, based on usage). I can easily include those keys in my application. But how can I secure my keys from prying eyes and abuse?
Upvotes: 3
Views: 407
Reputation: 73574
You can't secure it completely. You need to treat it as completely and totally compromised, because there is a workaround to everything you can put in place.
It's the same with WinForms apps.
Related from when I was asking for something similar: Common vulnerabilities for WinForms applications
Short version - Even if you store these keys elsewhere, if the end user can decompile your code and see how your code is accessing those keys, they can get at them.
The BEST you can do is add as many layers as possible (and reasonable) your defenses to make it as difficult as possible. Our approach is listed in this answer. You may be able to improve upon it. If so, please share, because we'd like to improve upon ours.
Upvotes: 1
Reputation: 22281
Consider refactoring your application to call the secured web services from your server and pass the results back to the client, thereby eliminating the need for credentials to be placed on the client side.
If the worry then becomes bandwidth, you could have the keys themselves not be packaged with the binary, but instead downloaded upon and encrypted. See http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx.
No matter how you do it, if the service is getting called from the client, the user could still access it.
Edit: Question: how do I secure the exposed service Answer: You can't, but you can make it harder.
To start out with, have a client certificate that gets installed that secures the communication channel from the client to your service.
Next, include a server generated nonce that requires the client to read a string of bytes from a known dll or exe in your deployed code at a random offset as requested by the server. If the deployed object is protected by legal measures from redistribution, you can sue to the moon if someone writes a third party client as they would have to redistribute the image you use for protection along with their application.
Ensure that your web service has throttling per user. Limit each user to 100 clicks per hour - or whatever is the line between fake and real.
Report and audit. Record the hits to the expensive web services and periodically validate that they were generated in a manner consistent with your application's usage.
Randomize. If you feel like making life difficult for anyone trying to reverse engineer your software, ensure that you randomize the URI used to hit your service on at least a daily basis. Create a function that uses the date as a seed and returns a unique URI for that day.
Obfuscate - at this point, you need someone who is really rather set on attacking your application. To further ruin his day, run your compiled binaries through a good obfuscator to ensure that
Once again, none of these ensure that the service cannot be used outside of your service, but they make it pretty difficult. If you really need to ensure that only your software can hit your service, use a crypto token to distribute your application's private key. That way, the only way they can hit the service is if someone has the device physically attached to their computer.
Upvotes: 1
Reputation: 24739
A platform independent way might be to store encrypted keys. Or, if the keys will rarely or never change over the lifetime of the app, hard code them.
Upvotes: 0