Where to store hashes, salts, keys in Desktop Applications

encryptionSecurity

I am trying to figure out where or how i should store application secrets and keys inside a desktop application.
For example a facebook app key or dropbox key and secret.

So I've read that i should hash, salt, encrypt etc etc these values. This is to prevent someone from reverse engineering my code and seeing the keys.

The is all good and well, but with all these methods, i'm just storing a salt or hash value somewhere instead of the key itself, in the end. Surely if a hacker can get to the salt/hash and possibly the source code, they will be able to decrypt the encrypted key and get my password/key/secret anyway?

One option I've read about that seems the most secure is to not store this value in the desktop app at all, but to call a web service to obtain the key (probably encrypted). But my question is, even in this case, a decent hacker will surely just do a memory dump or something to see what the value returned from the web service is, and then we're back at square 1.

The next best alternative seems to be obscurity.

Am I missing something completely?

On a side note, what use will a facebook/twitter/dropbox/etc key/secret be to a hacker anyway? Surely they would still need a user's credentials or access token to be able to use it anyway?

Any advice or suggestions will be appreciated.

Best Answer

There is no 100% secure solution. What ever you implement must be executable by a deterministic computer, so someone and substitute that and unpick what ever technical barriers you put in their way. You can make it more technically challenging and a more involved and slower process, but in time if the incentives are there, someone will break it.

If you are implementing this in .NET then, by default it is trivial for someone to obtain C# style source code to your application, and then to step through their C# code in a debugger. It is a little more complex in C/C++, but again not impossible. I do not know how much of a challenge this is with JAVA, but I would not expect it to be a significant hurdle.

There are processes that can be applied to make the code harder for a human to read, but do very little to make it harder for a computer to single step through the code. Someone can put a breakpoint in the system library and then back track up the call stack to see if this call to a network socket is of interest without having to understand your code base.

I have also seen encryption techniques used, where a program decrypts the actual code during run time. However, again, a determined hacker can just run this part of the code, obtain the decrypted code and then reverse engineer this into source code.

The best solution is to assume it will become compromised, and then ensure that the process for changing the sensitive data is trivial for you, and to process to compromise the sensitive data is as hard as possible for everyone else. That's why some systems require a web call to obtain the data. You can then block calls from IP's or from client certificates that you no longer trust, and give everyone else 'this months' application key.

In the end, you need to consider the consequences for having the data publicly known, and then decide how far you need to go, to make the process for obtaining it more skilled and and more time consuming.

Related Topic