6

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.

jww
  • 97,681
  • 90
  • 411
  • 885
Petey B
  • 11,439
  • 25
  • 81
  • 101
  • You are misusing the certificate and a private key. Proper implementation doesn't need to pull the private key to perform decryption. CryptoAPI functions let you perform operations using that key without having it as extractable. As you didn't specify what exactly functions you use, I can't comment further. – Eugene Mayevski 'Callback May 06 '11 at 15:06
  • @Eugene, I'm instantiating an RSACryptoServiceProvider from the X509Certificate.PrivateKey I pulled out of the cert store, then decrypting using that – Petey B May 06 '11 at 20:12
  • @Eugene Mayevski 'EldoS Corp , I added the code to my question, thank you. – Petey B May 06 '11 at 20:44
  • Why don't you use ASP.NET .config file standard encryption feature? – Simon Mourier May 07 '11 at 06:47
  • @Simon Mourier, that encryption uses generated machine keys, we are using managed keys that we have backed up incase of machine failure. Also I'm building this library to be used with all .Net applications, but in this case it is an APS.Net server. – Petey B May 09 '11 at 15:50

4 Answers4

2

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.

GSerg
  • 76,472
  • 17
  • 159
  • 346
Virat
  • 21
  • 3
1

If you have a certificate with a private key, it makes sense to employ PKCS#7 / CMS encryption of the AES key. This lets you decrypt the data with non-exportable private keys.

Unfortunately .NET doesn't seem to offer classes for CMS encryption. CryptoAPI does offer such functions (CryptEncryptMessage and CryptDecryptMessage), but they need to be called via P/Invoke, which can be to some extent non-trivial. For C# sample of doing this see the source code here.

An alternative option would be to use our SecureBlackbox components (TElMessageEncryptor, TElMessageDecryptor), though in your case this might be an overkill.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
  • Can you please give me an example of the use of this two components (TElMessageEncryptor, TElMessageDecryptor) to encrypt and decrypt a file with PKCS#7 format and using digital certificates? I have downloaded the full package of secureblackbox but I couldn't find an example of this components – DkAngelito Sep 27 '11 at 23:00
  • @DkAngelito answered in our support forum. Samples\language\PKIBlackbox\MessagesDemo shows them. – Eugene Mayevski 'Callback Sep 28 '11 at 05:43
  • @Eugene Mayevski 'EldoS Corp Can you please give some pointer on this also http://stackoverflow.com/questions/34549899/ssl-connection-using-windows-certificate-store – User1234 Dec 31 '15 at 18:19
1

I think there are some inherent conflicts with your security model. You want an application running under the user "Network Services" to be able to decrypt the config file, but you want the encrypted information to be safe even if the "Network Services" user is compromised. Those two goals are at odds - either the user can access the data or it can't. I think the best you can do is segragate the security access, so that if "Network Services" on one machine is compromised, it does not compromise the security of other users or other machines. That is why the Windows security model provides each user on each machine with it's own private key, and that is the key used by DPAPI to encrypt/decrypt the config files.

You say that in your model, you are encrypting the config info with a standard set of keys. In this model, if one trusted user on one machine is compromised, then the attacker gains the key to access all the encrypted config data for all users on all machines. You say that you are using managed keys in case of machine failure. I would suggest that it is more secure to backup and manage the DATA being encrypted then to backup and manage the KEYS being used to access that data.

My suggestion is use the built in .Net methods of encrypting/decrypting the config data, which uses the Windows private key of the user on the local machine. (there's some examples of implementing the standard aproach here: http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx and here: http://www.codeproject.com/KB/security/ProtectedConfigWinApps.aspx) If any data is being put into the config files that is essential and would need to be recovered in case of machine failure, then send that data to your database or other central data store as a backup. This avoids using the same managed key or keys for all your deployments.

Tony
  • 953
  • 1
  • 10
  • 22
0

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

You are correct in that any service running under Network Services that is compromised could potentially access the private key. Sometime in 2005 or so, Microsoft realized it and starting creating unique service accounts to limit damage caused a common compromised service, like Network Services. For example, SQL server was moved to its own service account, IIRC.

The underlying problem is a security design problem with Microsoft's model, and there's not a lot you can do with it. Microsoft realized it, and moved to a slightly different model with CryptoNG, IIRC. Under CryptoNG, the operations using the private key are out-of-process and IPC is used to communicate requests and results back and forth between the service and the process that performs key operations. This mostly side steps the issue you are concerned about.

Even under the new model, you will still need software that's cognizant of the model. You should be fine with say, IIS 7, but Apache may cause problems because its model only recognizes file system ACLs.

Moving key operations out-of-process is becoming a standard practice. For example, GnuPG does the same. GnuPG uses a library called libassuan that performs the marshaling of requests and results between consumers and producers.

I would not worry too much about the efficiency concerns between the client and server in the out-of-process model. Windows Pipes, Unix Pipes and Unix Domain Sockets are lightening fast. Also, its a lot like Dr. Jon Bentley said: If it doesn't have to be correct, I can make it as fast as you'd like it to be.

jww
  • 97,681
  • 90
  • 411
  • 885