C# – Securely Handling Private Keys from Windows Key Store

ccryptographyprivate-keySecurityx509

I'm working on an application that encrypts configuration file settings for an ASP.Net web server. The encryption method I'm implementing is enveloping data using AES and RSA. I'm generating an AES Key, using that AES key to encrypt my data, then encrypting the AES key with the public key from a certificate in my Windows Certificate Store. I then save the data, along with the encrypted AES key, and the certificate serial number used to encrypt it, back to the configuration file.

When I want to access this data, I read the serial number of the certificate used to encrypt the AES key, pull out the private key from that certificate, and decrypt the AES key, then decrypt the data using that key. Here is where I am unsure of my level of security.

In order to access the private key associated with the certificate, I must mark the private key as exportable, and give the user my application runs under access to the private key. Since this is an ASP.Net server, that user is "Network Services". I'm sure you can see why this would be a security issue. Basically if anyone were to break into my ASP.Net server over the web, perhaps through some sort of injection, they would have access to that private key, would they not?

Does anyone have any suggestions as to how I could make my model more secure?

Decrypt Function:

//need an rsa crytpo provider to decrypt the aes key with the private key associated with the certificate
using (RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider) decryptionCertificate.PrivateKey)
{
    //decrypt the aes key with the cert's private key
    byte[] aesKey = rsaCSP.Decrypt(encryptedAESKey, false);

    //decrypt data using the decrypted aes key and the IV passed in
    decryptedData = decryptWithAes(encryptedData, aesKey, aesIV);
}

Thanks.

Best Answer

Just by writing

RSACryptoServiceProvider rsaCSP = (RSACryptoServiceProvider)decryptionCertificate.PrivateKey

it doesn't mean that you are assigning the actual "key". You can make the private key Non-Exportable and still would be able to perform decryption.