10

I'm working on a software project where the application will end up being run in an untrusted environment. I have a need to perform some ancillary cryptographic signing (meaning this is not the primary means of securing data), but do not wish to leave the key in plain view as such:

private static final String privateKey = "00AABBCC....0123456789";

What method can I use to reasonably secure this? I'm aware that nothing is full proof, but this will add an extra layer in the security wall.

For clarification: I've got what is essentially a String that I don't wish to have easily pulled out in a debugger or via reflection. I'm aware that decompilation of the class file could essentially render this moot, but that's an acceptable risk.

Obviously storing the key offsite would be ideal, but I can't guarantee Internet access.

Jason Nichols
  • 11,603
  • 5
  • 34
  • 53
  • Please elaborate on the constraints and what you mean by "untrusted environment " and "in plain view". – Mark Carey Jan 12 '10 at 16:14
  • Do you care if someone sets a breakpoint on Mac.getInstance() and then traces the code until they find your key? – kdgregory Jan 12 '10 at 16:19
  • kdgregory, I care but I'm not sure there's any way around it. – Jason Nichols Jan 12 '10 at 16:26
  • Having seen your response to my post, I think the only follow-up is to give a longer description of your application and deployment process. Perhaps you can load the key from external configuration. If not, then I'll agree with *Kevin* that it's probably not worth applying any obfuscation whatsoever. – kdgregory Jan 12 '10 at 16:46

5 Answers5

8

It's impossible to secure a key in an untrusted environment. You can obfuscate your code, you can create a key from arbitrary variables, whatever. Ultimately, assuming that you use the standard javax.crypto library, you have to call Mac.getInstance(), and sometime later you'll call init() on that instance. Someone who wants your key will get it.

However, I think the solution is that you tie the key to the environment, not the program. A signature is meant to say that the data originated from a known source, and has not been tampered with since that source provided it. Currently, you're trying to say "guarantee that my program produced the data." Instead, change your requirement to "guarantee that a particular user of my program produced the data." The onus is then shifted to that user to take care of his/her key.

kdgregory
  • 38,754
  • 10
  • 77
  • 102
  • I agree with your sentiments and solution wholeheartedly. Unfortunately the deployment constraints won't allow me to change the requirement as you describe. In this case, I'm looking to ward off an attack up to a given level of sophistication. If resistance up to someone half skilled with a debugger is all that's possible, then so be it. – Jason Nichols Jan 12 '10 at 16:42
2

Forget about obscuring it in the code. It will only make your software harder to read, debug and maintain. You'll also be nailed if your software has to go through a security audit.

If you can't put the key in secure storage (securely on disk, secure memory or a passphrase in someones head), don't bother with anything else.

If you're in a *nix environment, storing the key on disk with root/root 400 permissions might be "good enough".

On Windows, you could use the DPAPI to store the data in Microsofts secure memory.

You could also use a lightweight PBE to encrypt the sensitive key and have the user enter the passphrase when the application starts up.

Kevin
  • 30,111
  • 9
  • 76
  • 83
0

Whose private key is that? The private key is supposed to be private, so it is wrong to distribute it.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
0

First off - good on you for thinking about this problem!

Is it possible to instead generate a private key, communicate with your Certificate Authority and have it sign the key (and manage a CRL as well)?

As an alternative, if this is going to be running on Windows, you can use the Crypto API to securely store a private key that is marked as not-exportable. How you distribute that key securely can be another challenge though.

Goyuix
  • 23,614
  • 14
  • 84
  • 128
0

Can you break the private key out into two parts: store one in your program, then interactively request the second half - when your app starts ?

monojohnny
  • 5,894
  • 16
  • 59
  • 83