Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to securely store a PrivateKey in code [duplicate]

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.

like image 501
Jason Nichols Avatar asked Jan 12 '10 16:01

Jason Nichols


People also ask

How do I store Privatekey?

The most secure method of storing your private keys is to use some form of cryptographic hardware storage device. While they can be expensive, tools like Hardware Storage Modules (HSM), Smart Cards, or USB tokens are great lines of defense against an attack.

Where should private key certificate be stored?

Where to store the private key? Generally, the best practice is to generate the private key along with the CSR on the server where you intend to install the SSL certificate. This way, you eliminate the risk of vulnerability during the transfer from one machine to another.

Is it safe to store private key in database?

Private key can't be hashed, we need its actual text. A suggestion is to symmetrically encrypt the private key before storing in the database with the user's password. But this means that the user needs to decrypt the private on every transaction, which is kinda user unfriendly.


2 Answers

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.

like image 92
kdgregory Avatar answered Oct 25 '22 05:10

kdgregory


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.

like image 28
Kevin Avatar answered Oct 25 '22 06:10

Kevin