7

In my C application I have a decryption key that is used to decrypt sets in the database (username / password). Currently, I simply declared it with

char * key = "$$$secretSampleDecryptionKey$$$";

Shortly after that line, I prepare the SQL statement and then select from the DB. My question is, if someone was to debug my compiled application or dissassemble it, will they actually see the key? What can I do to hide it from them?

EDIT:

As Mark and Aaron pointed out, I can simply use the Linux / Unix strings command

strings nameOfApplication

to print out all the strings in my application, including the "secret" key.

EDIT 2:

The app runs on my server and the database stores sensitive customer data that is encrypted. I thought I was playing it safe by not having the key in a text file for everyone to read but compile it instead.

Bevor
  • 8,396
  • 15
  • 77
  • 141
Frank Vilea
  • 8,323
  • 20
  • 65
  • 86
  • 4
    The unix stings command will show all text in the file - so no need to disassemble – mmmmmm Sep 06 '11 at 11:39
  • 1
    Long story short, whatever is on the client's computer is as good as cracked. Either don't put anything of interest there or accept it and save everyone headaches ;) –  Sep 06 '11 at 11:43
  • I tried the strings command and it does indeed show the entire key and right after that entry it shows the sql statement, so everyone would know about that. Thank you so much for pointing that out to me. – Frank Vilea Sep 06 '11 at 11:44
  • @delnan, I understand what you mean. The application actually runs on a web server and I was hoping that if an unexperienced hacker was entering the machine "by accident" / or out of luck I could at least prevent them from easily accessing the encrypted customer data. – Frank Vilea Sep 06 '11 at 11:47
  • I want to point to my answer to a similar question yesterday: [Is this a wise way to protect a datafeed?](http://stackoverflow.com/questions/7306216/is-this-a-wise-way-to-protect-a-datafeed/7308755#7308755) – Paŭlo Ebermann Sep 06 '11 at 13:45
  • If someone gets access to your database and your binaries, it's game over security-wise - don't expect that expending effort on obfuscating the key is going to make the slightest bit of difference to someone who made it that far. Besides, they probably have root and can just read the key out of your app's memory. – Nick Johnson Sep 07 '11 at 05:11

5 Answers5

10

An interesting link relating the story of someone retrieving a password from a binary :

Deconstructing an ELF File

This is a step-by-step description of what someone could try to discover a password. It will give you some idea of what "not to do". The use of the command strings is the first item in the list for example.

If you want to hide your secret string from strings, you can store it in as a char array not terminated with \0 character. strings should not pick it up.

There is also a nice trick mentioned (which is bypassed) to avoid someone to use a strace/ltrace on your binary.

Ultimately by disassembling the code, the "hacker" manage to retrieve the password, which as other have pointed out is difficult to protect against. Basically you can't really hide anything in a binary...

Xavier T.
  • 40,509
  • 10
  • 68
  • 97
4

If the key is in your source then an attacker will be able to find it. The best you can do is to make it more difficult for them.

The stored key should not be text, but binary. That way you avoid searches for strings. Presumably if you have the key present in the code your users do not need to be able to type it in.

Store the key in at least two random looking binary arrays that are XOR'ed together to make the actual key. Alternatively, pick one of the standard text strings that is present in your application anyway, something like: "Please enter the Zipcode: ", and use that as your key, or as one component of the XOR. Hashing such a message would get it to a standard length if needed.

rossum
  • 15,344
  • 1
  • 24
  • 38
  • storing they in binary format does also not help. There are tools to find keys in binary files such as memory images. Instead of using a string that is already present you could use any binary sequence of your program (be careful when updating the program but this way there are more possibilities than just using a string). The Problem is that with reverse engineering tools an attacker can find out where you are getting the key from. – mrks Sep 07 '11 at 11:34
  • @markus: Of course. All you can do is to make it difficult for the attacker. At some point the key will have to be in memory and the attacker can always get it from there. Single stepping through the appropriate piece of assembler/bytecode is also possible. – rossum Sep 07 '11 at 20:16
1

Using a debugger / disassembler the user will always be able to find out the password. You can make it harder (e.g. use obfuscation), but not impossible.

If you really do have a secret (i.e. a private key needed to decrypt the data), you can perform decryption on a smartcard.

In your scenario concerning usernames and password, you might just store the password-hash in the database (see referenced answers in Best way to store password in database)

Community
  • 1
  • 1
rumpel
  • 7,870
  • 2
  • 38
  • 39
  • Thanks Rumpel. I kind of like the idea to store the key in the database. At least it is better than everyone being able to easily read it. – Frank Vilea Sep 06 '11 at 11:57
1

Can someone see it?

The command strings will show the string, no need to disassemble the application.

Disassembling will just make it more simple to identify which of the 15'000 strings is used as key.

What can I do to hide it from them?

There is only one solution: Don't put it in the code.

Instead, use a license key or similar technique where the user knows the key.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
1

I wonder if someone could give us a real answer to solve this problem. From my experience as an web dev I can tell you that what you give to client does not belong to you anymore to control. Consider a website using some encryption algorithm on the server-side and a hard-coded javascript technique on the client, and the webdev, himself, guided by his own vanity, do not want to show it to the world, but still to be used by the clients, as it is.

In this case, what can he do? Yes, yes, he can come up with the idea to put his script in an infinite loop based on setTimeout, all as an anonymous function, so it can't be tracked, but still the initialisation must be done somewhere, the code must be visibile, further more, he decide to send the code after load in an encrypted way, but still, on the client you wil still have to have the decryption key, so someone who want's the information will still have the two necessary pieces of this puzzle. But our programmer is perseveringly, so he creates the decryption function every time to match only one encrypted string, but still it does him no good. As the client will still have the string and the matching function.

Anything he can do is to find a way to use the environment so that the function can be used only one time, after that the code used to expire as the string, and the real information to be lost forever. And the thing with the highest importance is to make the use of the environment in such a way that the context of the execution of the decryption function can not be forged.

I know that I do not answered your question but I pin pointed some important details of the problem you mentioned. If you work with C there must be some tools you can use, as creating a context using some memory state or an actual system operation to get you something that can't be forged.

EDIT 1: You could create an interesting domino efect in your code leaking bits of the encryption key based on the execution as when it is needed you wil have it entirely but it would not be stored in a file or in a string in your compiled file, so it can only be found at runtime, and it only be found in some specific conditions, and further more it might take some hrd reverse engineering to get it. Might be a good solution.

With great respect, Paul

khael
  • 2,600
  • 1
  • 15
  • 36
  • Even with the use of a licence key, as @Aaron mentioned, it is problematic, as if you really want to hide that key, or you want to prevent different users to use it, it is still impossible. Only if your entire code mechanism is like basing on that string to work, and it is unique on each system itself. – khael Sep 06 '11 at 12:11