??? Which Key Encrypts .Config Files ???

T

Tom Baxter

Hi everyone,

I have a small block of code that encrypts a database connection string in a
..config file, but I'm not sure where the encryption key comes from. There is
no problem with this code -- it seems to be working fine -- I am able to
retrieve the connection string with no problem after it's been encrypted.

Let me show you the snippet of code that performs the encryption:

using System.Configuration;
// ...
ConnectionStringSettings settings = new ConnectionStringSettings;
settings.Name = "MyConnString";
settings.ConnectionString = "DataSource=...;password=...";
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings.Add(settings);
config.ConnectionStrings.SectionInformation.ProtectSection(null);
config.Save();



When I look in the resulting .config file, here's what I see:

<configuration>
<connectionStrings
configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element"
xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>Rsa Key</KeyName>
</KeyInfo>
<CipherData> <-- I BELIEVE THIS IS THE ENCRYPTED
KEY -->
<CipherValue>ej/sRsbuZIC3ZnpxLvQbveZMzzEB51jWkCUDN93X38MMcXtR0uJ2LCe2ZbNWWyu/v5nFg5o+i9U3roEFSd0h6hKXPWkO5DkU6KOGRLwhwEE/H+XVGzEVwI10OMKClMYo/hPB7hzD9ILb2yDzdKjHlCTaKBs5Rr3zSD8Ez3YhvP8=</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData> <-- I BELIEVE THIS IS THE ENCRYPTED CONNECTION
STRING -->
<CipherValue>gXZlWUm53KNigp2H8oa7b1DUkeSDlQnWuaqQwFNCpRf74GheR6HFPnXXlGvyOaU0ekcEvRZOKKCrkDSOXP6lxlp5qttC/1Ab0QcCJc1FJWvEkn0J/mBZdByyaRxg7UoxFyBn5fQ448LaUhd6JPCe2JW2V9AnkCDDuUquWYoO3cFCYZtSpr4zo8tnimYxIJrwoNBDWY/PO8lq6dO+S/me6yw7CTN6njZ1eATGIgKI8VQxJDuPLvIemVLc83/900OJO3iBgukFuSY=</CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
</configuration>


Notice the first <CipherValue> element (nested within the first <CipherData>
element). I believe this <CipherValue> element contains the encryption key
used to encrypt the connection string, and this encryption key is itself,
encrypted. Every time I run the code snippet a *new* encryption key is
generated.

Now, here is my question: Since the encryption key is being stored in the
..config file, and since this encryption key is itself encrypted, what key is
being used to encrypt (and decrypt) the encryption key? Where is this key
stored?

Think of it like this: The encryption key stored in the .config file is used
to encrypt and decrypt the connection string. Since this encryption key is
itself encrypted within the .config file, it *must* have been encrypted
using some other key. Whatever and wherever this other key is, it is also
used to decrypt the embedded encryption key.

Secondarily, is this a security risk? If the key used to encrypt and decrypt
the embedded encryption key is available (and it might be since I don't know
where it's coming from) and if someone gets my .config file, they could
decrypt the embedded encryption key and then use that key to obtain the
connection string, right?

I hope this is clear. I've done a lot of reading and haven't found an
answer.

Thanks very much for reading this far.
 
J

Jon Skeet [C# MVP]

Notice the first <CipherValue> element (nested within the first <CipherData>
element). I believe this <CipherValue> element contains the encryption key
used to encrypt the connection string, and this encryption key is itself,
encrypted. Every time I run the code snippet a *new* encryption key is
generated.

Now, here is my question: Since the encryption key is being stored in the
.config file, and since this encryption key is itself encrypted, what key is
being used to encrypt (and decrypt) the encryption key? Where is this key
stored?

Reading through the docs, I believe it's a machine-level or user-level
RSA key container, and the user account which executes the page
request must have access to that RSA key container in order to work.

In other words, it's using underlying Windows security - so I don't
believe it's a security risk.

One way to test it would be to copy the configuration and application
to another machine - I'm pretty sure you'll find it doesn't work.

Jon
 
J

Jialiang Ge [MSFT]

Hello Tom,

From your post, my understanding on this issue is: you wonder where the
encryption and decryption key is stored when you encrypt the configuration
nodes. If I'm off base, please feel free to let me know.

I notice that you are using RsaProtectedConfigurationProvider, the RSA
mechanism, to encrypt the configurations. RSA needs two keys: one is public
key which is used to encrypt the content; another is private key, to
decrypt the content. According to the MSDN article
http://msdn2.microsoft.com/en-us/library/ms998283.aspx, the key pair for
the current application is stored either in machine level key container, or
user level container. For RsaProtectedConfigurationProvider, it uses
machine level key container by default. Machine level keys are stored in
the directory:
C:\Documents and Settings\All Users\Application
Data\Microsoft\Crypto\RSA\MachineKeys
Each file in the directory represents one key container (public - private
key pair).
You could use the command:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -pc
"keycontainer_name" -exp
to create a new key container with the specified keycontainer_name.

But actually, it is not the public key of RSA key container that encrypt
the content of configuration information, because RSA is a kind of
asymmetric encryption, and it is slow to encrypt large messages. We usually
use symmetric key cipher, such as DES, to encrypt large messages. When we
start to encrypt the content of a configuration file,
Firstly, it will find the RSA key container according to the key name
specified in <EncryptedData><EncryptedKey><KeyInfo><KeyName> node.
Secondly, it randoms a DES key and use the public key from the key
container to encrypt the DES key. Then store the encrypted result in the
node <EncryptedData><KeyInfo><<EncryptedKey><CipherData>
Lastly, it uses the DES key to encrypt the configuration information.

When we decrypt the configuration information,
Firstly, it will find the RSA key container according to the key name
specified in <EncryptedData><EncryptedKey><KeyInfo><KeyName> node.
Secondly, it use the private key to decrypt the encrypted DES key.
Lastly, it uses the DES key to decrypt the configuration information

For more information, please refer to the page
http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html

Please let me know if you have any other concerns, or need anything else.

Sincerely,
Jialiang Ge ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
For MSDN subscribers whose posts are left unanswered, please check this
document: http://blogs.msdn.com/msdnts/pages/postingAlias.aspx

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications. If you are using Outlook Express/Windows Mail, please make sure
you clear the check box "Tools/Options/Read: Get 300 headers at a time" to
see your reply promptly.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jon,

But if you can only decrypt the config file on the machine it was encrypted
on how do you distribute an enecryted configuration file?

Thanks,
Mike
 
J

Jon Skeet [C# MVP]

Mike said:
But if you can only decrypt the config file on the machine it was encrypted
on how do you distribute an enecryted configuration file?

Not sure, to be honest. I suspect it's not really designed for that
kind of scenario though - as soon as you're distributing something,
you'd have to have a shared key somewhere. It could be that there are
ways of tying the key container to an active directory domain account
which the servers could use - but I'm inexperienced (understatement!)
in this area.
 
C

Chris Mullins [MVP - C#]

Mike said:
But if you can only decrypt the config file on the machine it was
encrypted
on how do you distribute an enecryted configuration file?

This gets tricky. The encryption / decryption of the config file is done
using DPAPI, which is build into all the current flavors of Windows.

This API relies on a password hash that's tied to the credential of a
particular account. To make this work in a distributed scenario, you need
to:

- Create a service account in your Active Direectory ("MikesAppAccount"),
and grant it some specific right.
- Make sure the "Password doesn't expire" field is checked, or it's a
timebomb...
- You need to enable roaming profiles for the account.
- do the encryption / decryption from a processing running as
"MikesAppAccount".

The document you want is here:
http://msdn2.microsoft.com/en-us/library/aa302392.aspx

.... adn the section is "Storing Database Connection Strings Securely"

I've actually used their pattern before, using a COM+ component (now with
the fancy "Enterprise Services" name) to do the encryption/decryption and it
worked quite well. It was many years ago though, and most of the details
have been paged out of memory...
 
T

Tom Baxter

Jialiang,

Thank you. Your information is perfect.

From what you described, it seems there there is the (slight) possibility of
another application, on the same machine, being able to decrypt the .config
file. This seems true since the RSA key pair is stored on the local machine
(in C:\Documents and Settings\All Users\Application
Data\Microsoft\Crypto\RSA\MachineKeys).

Would you agree?

Thank you again for the great response.
 
J

Jialiang Ge [MSFT]

Hello,

The machine level key containers folder can only be accessed by the users
in Administrators group of the system. For other users, they need to be
granted with access permission. Therefore, it should be safe as long as we
maintain our Administrator accounts properly.

If you have any other concern or need anything else, please feel free to
let me know.

Sincerely,
Jialiang Ge ([email protected], remove 'online.')
Microsoft Online Community Support

=================================================
When responding to posts, please "Reply to Group" via your newsreader
so that others may learn and benefit from your issue.
=================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
T

Tom Baxter

Thank you, Jialiang. This is a great answer.




Jialiang Ge said:
Hello,

The machine level key containers folder can only be accessed by the users
in Administrators group of the system. For other users, they need to be
granted with access permission. Therefore, it should be safe as long as we
maintain our Administrator accounts properly.

If you have any other concern or need anything else, please feel free to
let me know.

Sincerely,
Jialiang Ge ([email protected], remove 'online.')
Microsoft Online Community Support

=================================================
When responding to posts, please "Reply to Group" via your newsreader
so that others may learn and benefit from your issue.
=================================================
This posting is provided "AS IS" with no warranties, and confers no
rights.
 
D

Dominick Baier

Hi,

you have 2 options:

a) encrypt the config locally (usually at install time)
b) distribute the keys

the aspnet_regiis.exe command line tool has all the options for b) (create
keys, export keys, import keys, acl keys)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top