0

I have a C function which uses a private key and want to prevent that anyone can read out this key. Not only from the binary - but also from the source repository. The key is not in plaintext, but still it should be as difficult as possible to get access to it. My plan is to compile this c file to an object file and place this object file (with the obfuscated privateKey array) into the source repository. But I'm not sure about in which storage-class/scope I should put the key (local stack variable, static variable - local/global, ...).

1.) Global static

static unsigned char const privateKey[] = {
  0x44, 0x8e, 0x54, 0xae, 0x64, 0x74, 0xbe, ...
};
void myFunction(){
  //do something with privateKey
}

2.) Local Stackvariable

void myFunction(){
  unsigned char const privateKey[] = {
    0x44, 0x8e, 0x54, 0xae, 0x64, 0x74, 0xbe, ...
  };
  //do something with privateKey
}

3.) Local Static

void myFunction(){
  static unsigned char const privateKey[] = {
    0x44, 0x8e, 0x54, 0xae, 0x64, 0x74, 0xbe, ...
  };
  //do something with privateKey
}

I just viewed the object files of these 3 solutions with nm - at the 2nd solution I don't even see a symbol for the keys (but I'm afraid with using a Debugger it's easy to read the key, cause it's placed on the stack at runtime). Solution 3 looks in nm like:

00000000 T myFunction
00000200 t __6_privateKey.2

and Solution 1 like:

00000000 T myFunction
00000200 t privateKey

Where is the most secure storage-class to put the key in - or is there no difference in terms of security at all? Is there another more secure solution?

Constantin
  • 8,721
  • 13
  • 75
  • 126
  • There is no such thing as secure storage class, unless you protect it with user-specified password. Then it will be somewhat secure. Take a look at PKSC12 (http://en.wikipedia.org/wiki/PKCS12) for some info. – Valeri Atamaniouk Mar 05 '14 at 09:42
  • 1
    You don't have to call the variable privateKey. You could make it something obscure like x. To make the code readable, **#define privateKey x**. So the code can use privateKey but the internal linker variable is x. – cup Mar 05 '14 at 09:48

3 Answers3

6

Wherever you put it, it will be stored in the executable file as some constant array which will by copied if you use a dynamic storage class (eg: local var). I don't think using any of that trick will change anything about the security of the key.

One general advice: if you are trying to reinvent some cryptographic wheel. Don't do it. It is extremely likely that you will fail. Many famous attempt failed before you (WIFI security, DVD encryption...)

hivert
  • 10,579
  • 3
  • 31
  • 56
  • Not least as anyone with access to the repo could build a simple program to link to the object file in the same way. Your only option is to encrypt the key with key material not stored in the repo, or store the key outside the repo. – abligh Mar 05 '14 at 09:46
3

If your user's computer can execute the code and access the data, then so can the user who controls the computer. There is no such thing as "something only the program can see".

While there are some attempts at making "tamper-proof software", like TPM, I don't think that will solve your problem (that would essentially require the user to cooperate and promise not to look while you're executing). You need to change your higher-level policy to change your requirements.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

Other answers are correct. You cannot hide the key from the user who needs to use it.

The best you could do is place the key onto a physically different computer, and use the network (internet/local area network) to deliver the key. Of course this adds further problems in that you need to authenticate the user, and secure the key in transit.

This is a wide area of expertise, known as Key Management.

There is one solution outlined in an answer I gave here: How to properly do private key management

Community
  • 1
  • 1
PaulG
  • 13,871
  • 9
  • 56
  • 78