6

I have a simple encryption application where I will be encrypting "sensitive" data in a database. Only the people who have access rights can see these data in decrypted form. I have been looking around for more information on how to do that and here is my project approach:

  1. I am using AES encryption algorithm.
  2. Generate an AES key with RNGCryptoServiceProvider. Encrypt info with AES key.
  3. Encrypt the AES key with and RSA public key.
  4. Store the private key in a USB file, which I will only give to the people who can have the access rights.
  5. When a rightful person needs to see the decrypted information, they will provide the private key. The app uses the private key to decrypt the AES key, which in turns decrypts the information.

Now, my question is how can I safely store that private key? From what I have been reading, I can obtain the private key using FromXMLString. But, I was thinking that if someone somehow gets the USB file and the XMLFile, he can find the private key by using the FromXMLString similarly. So, how can I protect that file, for example, by using a passphrase? Is there any function in c# i can use for that?

Also, if I change the key pairs, I have to change the public key and re-encrypt the AES key again with the fresh new public key. For that, I found this post How to Generate Unique Public and Private Key via RSA to be quite useful. But, something I am not sure about how the author implemented it. Does he also store the key container name in the private key file? Or the ToXMLString automatically does that?

Thanks~

Community
  • 1
  • 1
coffeeak
  • 2,980
  • 7
  • 44
  • 87

3 Answers3

5

Somehow, somewhere the decryption key or the RSA key to get the decryption key has to be kept as plain text. If it's not rather be a USB drive, it has to be in a user's head.

So something that you can do is to have multi-factor authentication. A password which only the user knows (He'll keep it in his head or write it down on a sticky note; not your call) and the USB drive which contains the other decryption key.

So an attacker will have to have both the password and the USB drive to get to the encrypted information.

Have a look on PBKDF2 on how to derive a cryptographically secure key from a password the user enters.

Ranhiru Jude Cooray
  • 19,542
  • 20
  • 83
  • 128
  • Thanks for the answer. So, you mean to derive a key from the password and use it to encrypt the private key file? – coffeeak Dec 19 '12 at 08:04
  • Yes that should work. So ultimately it's all based on the password the user keeps in his head. But that will not be multi-factor authentication then. Perhaps encrypt first using the key in the USB drive and then re-encrypt using key you get from deriving the password the user is supposed to remember OR you can `XOR` both keys to get a single key and then encrypt using that. – Ranhiru Jude Cooray Dec 19 '12 at 08:05
  • The XOR idea sounds good. Thanks! But, I think PBKDF2 derived key should be good enough. – coffeeak Dec 19 '12 at 08:18
  • 2
    If somehow the password is in the hands of an adversary, he can decrypt the information. However if multiple factors are taken in to consideration, the adversary requires access to the USB drive as well. Your call. – Ranhiru Jude Cooray Dec 19 '12 at 08:37
  • Well, let's say I use the XOR method. The private key file is now encrypted using the single Key (passphraseKey XOR private Key). I have to decrypt it before getting the private key. So, how do I get back the single key for decryption? – coffeeak Dec 19 '12 at 09:10
  • My idea was something like this. There are two keys. One is in plaintext inside a USB drive and one is in the user's head. So you XOR both those keys and encrypt the content. You don't need RSA in that case. – Ranhiru Jude Cooray Dec 20 '12 at 05:46
3

The problem with decrypting a private key is that the key will be transferred in plain into the main memory of your computer, and possibly in the swap within storage. There are a few options to use a private key without getting it into memory:

  • use a smart card, with a private key behind a PIN (PIN's are more safe than passwords as they are normally protected with a "retry count" (so you cannot try and brute force access)
  • use a security token, which is basically a smart card and smart card reader combined

Other options that are trickier to use:

  • use the onboard Trusted Platform Module (TPM) on the motherboard of your computer, which is basically a smart card on board
  • use some kind of protected key store provided by your operating system

Furthermore, you have an option to use a USB drive that can be protected with a PIN or password. Ironkey makes certified USB drives with AES encryption performed in the hardware of the USB key itself. Of course, this will move your private key into memory.

If you have to use a private key in memory, make sure your system is hardened properly, e.g. encrypt the swap, make sure you have a system to maintain access rights etc. etc..

Welcome in the realm of key management :)

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
2

I suggest storing certificates along with private keys in PKCS compatible containers (*.pfx). In C# this could be done with the Bouncy Castle library.

This is how to create the pair:

Is it possible to programmatically generate an X509 certificate using only C#?

And this is how to store it in a container (step 3):

http://web.archive.org/web/20100504192226/http://www.fkollmann.de/v2/post/Creating-certificates-using-BouncyCastle.aspx

Community
  • 1
  • 1
Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106