讲解以及源代码下载
ASP.NET 2.0: Encrypting Connection Strings
http://blogs.vertigosoftware.com/snyholm/archive/2005/12/16/1746.aspx
http://msdn2.microsoft.com/en-us/library/yxw286t2.aspx
中文
http://msdn2.microsoft.com/zh-cn/library/yxw286t2.aspx
ASP.NET 2.0: Encrypting Connection Strings
In ASP.NET 2.0, Microsoft added a handy utility for encrypting sensitive data in your web.config. I used it to encrypt connection strings, but it could be used for nearly any section. The familiar aspnet_regiis.exe utility is used to encrypt and decrypt the sections. It creates key containers to store the encryption keys. You use this utility differently depending on your environment. The dev environment is the simplest to configure because you’re probably working with admin privileges on your box. A single server environment is a little more complicated because you must give the website user account permission to the key container. A web farm or multiple server environment involves the most steps because you must also create a .XML file to export the RSA encryption keys.
If you don’t know which account your website is running under, you can figure it out by temporarily add this code to a web page.
Response.Write("<BR><BR>The current identity is: " + System.Security.Principal.WindowsIdentity.GetCurrent().Name)
Response.Write("<BR><BR>The logged in user is: " + Page.User.Identity.Name.ToString())
We tested the performance in our lab with both a "real" application and with a simple application that just contained a single web page that calls a database. Both applications maintained the same performance when using clear text and encrypted connection strings.
Prepare your web.config for encryption:
1. Convert your connection strings to use the new <connectionStrings> section inside the <configuration> section. Here is an example:
<connectionStrings>
<!-- SQL connection string for My Database -->
<add name="MySQLConnString" connectionString="server=(local);user id=MyDBUser;password=A$tr0ng_Password;database=MyDatabaseName" providerName="System.Data.SqlClient"/>
</connectionStrings>
You can access connection strings from your code like this:
private string MyConnectionString = ConfigurationManager.ConnectionStrings["MySQLConnString"].ConnectionString;
2. Add this attribute to the configuration node in web.config:
<configuration xmlns=http://schemas.microsoft.com/.NetConfiguration/v2.0>
3. Add this section inside the <configuration> section:
<configProtectedData>
<providers>
<add name="MyProtectedDataProviderName"
type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
keyContainerName="MyKeyContainerName"
useMachineContainer="true" />
</providers>
</configProtectedData>
Note: The PublicKeyToken value is a constant value that is used by most of the framework, including System.Web and System.Configuration.
Note: Run the aspnet_regiis command from the <Windows>\Microsoft.NET\Framework\<version> folder (usually C:\Windows\Microsoft.NET\Framework\v2.0.50727).
To encrypt connection strings on a development box:
1. To encrypt:
aspnet_regiis.exe -pef "connectionStrings" "C:\physical_location_of_my_web_app"
To decrypt:
aspnet_regiis.exe -pdf "connectionStrings" "C:\physical_location_of_my_web_app"
To encrypt connection strings on a single web server:
1. Prior to running the website, run these commands to create a key container and give the website user account permissions to use the key container.
aspnet_regiis -pc "MyKeyContainerName"
aspnet_regiis -pa "MyKeyContainerName" "NT AUTHORITY\NETWORK SERVICE"
2. Run this command to encrypt the <connectionStrings> section:
aspnet_regiis.exe -pef "connectionStrings" "C:\physical_location_of_my_web_app" -prov "MyProtectedDataProviderName"
To decrypt, run this command:
aspnet_regiis.exe -pdf "connectionStrings" "C:\physical_location_of_my_web_app"
To remove the key container, use this command:
aspnet_regiis -pz "MyKeyContainerName”
To encrypt connection strings on a web farm:
1. Create an exportable RSA encryption key. The utility will put the file in this folder: \Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys. The files have undecipherable names, but you can tell which is yours by the timestamp.
aspnet_regiis -pc "MyKeyContainerName" –exp
2. Create an .XML file for exporting this encryption key to your web servers. Be careful not to overwrite your old file – it does not give you an "are you sure" prompt!
aspnet_regiis -px "MyKeyContainerName" "C:\MyFileName.xml" –pri
3. Encrypt the <connectionStrings> section.
aspnet_regiis -pe "connectionStrings" -app "/MyVirtualDirectory" -prov "MyProtectedDataProviderName"
4. Deploy the .XML file to a local directory on your web servers.
5. On your web servers, run the following commands to import the custom RSA encryption keys, create a key container and give the website user account permissions to use the key container. Run these commands before using the encrypted web.config or else your application will throw this compilation error "Failed to decrypt using provider 'MyInsideProtectedDataProvider'. Error message from the provider: The RSA key container could not be opened."
aspnet_regiis -pi "MyKeyContainerName" "C:\MyFileName.xml"
aspnet_regiis -pa "MyKeyContainerName" "NT Authority\Network Service"
6. Deploy the application with the encrypted web.config file to your web servers. At a minimum, copy the <configuration>, <connectionStrings>, and <configProtectedData> sections.
7. To make sure that no one can decrypt the Web.config files that are encrypted by RSA key container, delete the .XML file from the Web server.
To decrypt:
aspnet_regiis –pd "connectionStrings" –app "/MyVirtualDirectory"
To remove the key container, use this command:
aspnet_regiis -pz "MyKeyContainerName"
References
MSDN: Security Practices: ASP.NET 2.0 Security Practices at a Glance
MSDN2: Encrypting Configuration Information Using Protected Configuration
Mohamed Sharaf's Blog
IOpine
Swesecure.com (in Danish)
http://blogs.vertigosoftware.com/snyholm/archive/2006/06.aspx