3

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.

2
  • security.stackexchange.com is a good place for this kind of question Commented May 5, 2015 at 15:41
  • This is a tough nut to crack. Ptolemy's answer agrees with my experience in the area: the most you can hope for is security through obscurity, which is not real security.
    – user22815
    Commented May 5, 2015 at 23:11

3 Answers 3

3

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.

2

I think there are two distinct problems here

1: Can I stop a user who has access to the client source code from getting at a hardcoded or configigured key /password the client needs to access a service

2: Can I stop a hacker who gains access to the users pc from accessing the users cached username/password my app is using.

so with 1, you shouldn't have this kind of shared key used by all your clients. ensure each user has their own credentials for the service. This makes then responsible for their own information only and allows you to ban abusers

with 2, as in @ptolemy's answer, dont store their username/password store a hash, or better yet use the username/pass once to get an api key and store that. Invalidate after a period of time or when you detect suspect behaviour such as multiple concurrent connections etc

0

You should use a cryptographic hash function: a hash function which is considered practically impossible to invert, that is, to recreate the input data from its hash value alone.

To authenticate a user your application will:

  • hash the password presented;
  • compare the value with the stored hash.

This way, if the password file is compromised, you haven't a massive security breach: the application asks for a password, not for a hash-key and the hacker cannot retrieve the password (the one-way function prevents the original password from being retrieved even if forgotten or lost).

Reverse engineering the hash function / application is not meaningful as there is nothing hidden in your code. The passwords are protected by the complexity of reversing the hash function.

Anyway the hacker could try a dictionary attack using a large list of pre-computed hashes for commonly used passwords. Usually even a small dictionary (or its hashed equivalent, a rainbow table) has a significant chance of cracking the most used words.

So the access to hashed data should be restricted (e.g. see Shadow file for Unix-like operating systems).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.