由于出现了“Failed to decrypt using provider 'RsaProtectedConfigurationProvider'”的问题,进行相关的搜索,找到这篇文章。加密的方式在使用“ASP.NET Development Server”即在vs右键网页进行浏览,是不会出现问题的,但是部署在win2003 iis上则报错。直接看解决方式。
J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley
Microsoft Corporation
July 2005
This How To shows how to use the RSA Protected Configuration provider and the Aspnet_regiis.exe tool to encrypt sections of your configuration files. You can use Aspnet_regiis.exe tool to encrypt sensitive data, such as connection strings, held in the Web.config and Machine.config files. You can easily export and import RSA keys from server to server. This makes RSA encryption particularly effective for encrypting configuration files used on multiple servers in a Web farm.
Objectives
Overview
What's New in 2.0
Summary of Steps
Step 1. Identify the Configuration Sections to Be Encrypted
Step 2. Choose Machine-Level or User-Level Containers
Step 3. Encrypt Your Configuration File Data
Web Farm Scenarios
Additional Resources
Configuration files such as the Web.config file are often used to hold sensitive information, including user names, passwords, database connection strings, and encryption keys. The sections that usually contain sensitive information that you need to encrypt are the following:
Encrypting and decrypting data incurs performance overhead. To keep this overhead to a minimum, encrypt only the sections of your configuration file that store sensitive data.
.NET Framework versions 1.0 and 1.1 had limited support for configuration file encryption. However, .NET Framework 2.0 introduces a protected configuration feature that you can use to encrypt sensitive configuration file data by using a command line tool. The following two protected configuration providers are provided although you can also implement custom providers.
This How To explains how to use the Aspnet_Regiis.exe tool with the RSAProtectedConfigurationProvider to encrypt sections of your configuration file. This provider uses RSA public key encryption.
Note ASP.NET automatically decrypts configuration sections when processing them; therefore, you do not need to write any additional decryption code.
To encrypt configuration sections by using the RSA protected configuration provider, perform the following steps:
Encrypting and decrypting data incurs performance overhead. To keep this overhead to a minimum, encrypt only the sections of your configuration file that store sensitive data.
If you store sensitive data in any of the following configuration sections, you cannot encrypt it by using a protected configuration provider and the Aspnet_regiis.exe tool:
For the configuration sections listed, you should use the Aspnet_setreg.exe tool, which is also available for previous versions of the .NET Framework.
For more information about using the Aspnet_setreg tool to encrypt data in these configuration sections, see Microsoft Knowledge Base article 329290, How to use the ASP.NET utility to encrypt credentials and session state connection strings.
The RSAProtectedConfigurationProvider supports machine-level and user-level key containers for key storage. Machine-level key containers are available to all users, but a user-level key container is available to that user only.
The choice of container depends largely on whether or not your application shares a server with other applications and whether or not sensitive data must be kept private for each application.
Use a machine-level key container in the following situations:
RSA machine key containers are stored in the following folder:
\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
Use a user-level key container if you run your application in a shared hosting environment and you want to make sure that your application's sensitive data is not accessible to other applications on the server. In this situation, each application should have a separate identity and the resources for the application—such as files, and databases—should be restricted to that identity.
RSA user-level key containers are stored in the following folder:
\Documents and Settings\{UserName}\Application Data\Microsoft\Crypto\RSA
This step shows you how to encrypt a connection string in the Web.config file. It shows you how to do this with the machine store and then with the user store.
The RSAProtectedConfigurationProvider is the default provider and is configured to use the machine-level key container.
To encrypt the connectionStrings section in Web.config
<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb; data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
aspnet_regiis -pe "connectionStrings" -app "/MachineRSA"
The above command with the–app switch assumes that there is an IIS virtual directory called MachineRSA. If you are using the Visual Studio .NET 2005 Web server instead of IIS, use the–pef switch, which allows you to specify the physical directory location of your configuration file.
aspnet_regiis.exe -pef "connectionStrings" C:\Projects\MachineRSA
Note The Aspnet_regiis.exe utility tool is located in the following directory:
%WinDir%\Microsoft.NET\Framework\< versionNumber>
For nested elements, such as the <pages> section which is inside <system.web>, the XML name must include the containing section groups; for example: "system.web/pages".
If the command is successful, you will see the following output:
Encrypting configuration section... Succeeded!
Note The RSA machine key containers are stored in the following folder:
\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
Your modified Web.Config file, with the connectionStrings section encrypted, should be similar to the following example:
... <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> <CipherValue>R7cyuRk+SXJoimz7wlOpJr/YLeADGnwJVcmElHbrG/B5dDTE4C9rzSmmTsbJ9Xcl2oDQt1qYma9L7pzQsQQYqLrkajqJ4i6ZQH1cmiot8ja7Vh+yItes7TRU1AoXN9T0mbX5H1Axm0O3X/285/MdXXTUlPkDMAZXmzNVeEJHSCE=</CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>d2++QtjcVwIkJLsye+dNJbCveORxeWiVSJIbcQQqAFofhay1wMci8FFlbQWttiRYFcvxrmVfNSxoZV8GjfPtppiodhOzQZ+0/QIFiU9Cifqh/T/7JyFkFSn13bTKjbYmHObKAzZ+Eg6gCXBxsVErzH9GRphlsz5ru1BytFYxo/lUGRvZfpLHLYWRuFyLXnxNoAGfL1mpQM7M46x5YWRMsNsNEKTo/PU9/Jvnh/lT+GlcgCs2JRpyzSfKE7zSJH+TpIRtd86PwQ5HG3Pd2frYdYw0rmlmlI9D</CipherValue> </CipherData> </EncryptedData> </connectionStrings> ...
<%@ Page Language="C#" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { Response.Write("Clear text connection string is: " + ConfigurationManager.ConnectionStrings ["MyLocalSQLServer"].ConnectionString); } </script> <html> <body/> </html>
MyLocalSQLServer is the name of the connection string you previously specified in the Web.config file.
Note If your ASP.NET application identity does not have access to the .NET Framework configuration key store, the following message is returned:
Parser Error Message: Failed to decrypt using provider 'RsaProtectedConfigurationProvider'.
Error message from the provider: The handle is invalid.
To grant access to the ASP.NET application identity
using System.Security.Principal;
...
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(WindowsIdentity.GetCurrent().Name);
}
aspnet_regiis -pa "NetFrameworkConfigurationKey" "NT Authority\Network Service"
If the command runs successfully you will see the following output:
Adding ACL for access to the RSA Key container...
Succeeded!
You can check the ACL of the file in the following folder:
\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
Your RSA key container file is the file in this folder with the most recent timestamp.
aspnet_regiis -pd "connectionStrings" -app "/MachineRSA"
If the command is successful, you will see the following output:
Decrypting configuration section... Succeeded!
To decrypt the connectionStrings section that specifies a physical path to your application's configuration file, use the -pdf switch as shown here.
aspnet_regiis -pdf "connectionStrings" C:\Projects\MachineRSA
The following steps show you how to encrypt a <connectionStrings> section by using the RSAProtectedConfigurationProvider (RSA) with a user-level key container.
By default, the ASP.NET applications run under the NT AUTHORITY \ Network Service account. When you access encrypted configuration sections using RSA encryption with the user-level key container, make sure that your application is running with the same user identity as the account you used to encrypt the data.
To encrypt the connectionStrings section in Web.config
<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb;data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
<configProtectedData> <providers> <add keyContainerName="NetFrameworkConfigurationKey" useMachineContainer="false" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" name="MyUserRSAProtectedConfigurationprovider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </providers> </configProtectedData>
aspnet_regiis -pe "connectionStrings" -app "/UserRSA" -prov "MyUserRSAProtectedConfigurationProvider"
For nested elements, such as the <pages> section, which is inside <system.web>, the XML name must include the containing section groups; for example, "system.web/pages".
If the command is successful, you will see the following output:
Encrypting configuration section... Succeeded!
Note RSA user-level key containers are stored in the following folder.
\Documents and Settings\{UserName}\Application Data\Microsoft\Crypto\RSA
Your modified Web.Config file, with the connectionStrings section encrypted, should be similar to the following example:
... <connectionStrings configProtectionProvider="MyUserRSAProtectedConfigurationprovider"> <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> <CipherValue>In7jNc0GA1eE5nvVR2hrHQ6cC1O1kMbfBXH0alBwlY2OBM4sMa8NbK4pBnUdxFkrx+oSzLYE8SHS6dYZwE3Uf5x7hk46Jx+Z/hn1hneWMyxWn23t41708lQzySsotYnzL5VOdR4P7MrIlhW9eSpbWp7PopSzcLxlGbs41dH7L3E=</CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>Zbu2LQQeiHaUFXWPjLvPR9OLwrozCZj5i2zvcEFlx/UICt2Cn0fTdy51dbHQRjTUXnOyx2PC5vptALXsvxrhPo5I+I2SCr21rRUQ5H55P0ejJZMsAirkNjdhCe5RflVLdK96a6Sw0cz93inWi4rNkE1SiXB76cD08Y+DHrsjmGkW8/TeHCK2f4xSykmdJGRwpxxdt2+3DxMjQPfg39Xkr4JjRlE6FvQ/R6hkEyyqLmCxUxbTV/+mcBcwyE3AzrbOIl+627SG1fP4ovLmMkNvjlTl5lCZnoj6</CipherValue> </CipherData> </EncryptedData> </connectionStrings> ...
<%@ Page Language="C#" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { Response.Write("Clear text connection string is: " + ConfigurationManager.ConnectionStrings ["MyLocalSQLServer"].ConnectionString); } </script> <html> <body/> </html>
Because your application must access the data using the same identity that you used to encrypt the data, you often need to run the encryption command using your application's service account identity. To do so, you can start a command Window by using the runas command as shown below specifying an appropriate domain and user name.
Runas /profile /user:domain\user cmd
When you run Aspnet_regiis from the resulting command window, it uses the specified identity to perform the encryption. This allows the application that uses the same identity to decrypt the data at run time.
If your application runs under a different account than the one used to encrypt the data, ASP.NET will be unable to access the RSA user-level key container and will generate the following error:
Parser Error Message: Failed to decrypt using provider 'RsaProtectedConfigurationProvider'. Error message from the provider: Keyset does not exist
aspnet_regiis -pd "connectionStrings" -app "/UserRSA"
If the command is successful, you will see the following output:
Decrypting configuration section... Succeeded!
You can use RSA encryption in Web farms, because you can export RSA keys. You need to do this if you encrypt data in a Web.config file prior to deploying it to other servers in a Web farm. In this case, the private key required to decrypt the data must be exported and deployed to the other servers.
To do this, you must create a custom RSA encryption key container and deploy the same key container on all servers in your Web farm. This won't work by default because the default RSA encryption key, "NetFrameworkConfigurationKey", is different for each computer.
To use RSA encryption in a Web farm
aspnet_regiis -pc "CustomKeys" -exp
The -exp switch indicates that the keys are exportable.
If the command is successful, you will see the following output:
Creating RSA Key container... Succeeded!
You can verify that a custom key container exists by looking for the file and checking timestamps in the following location:
\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA
\MachineKeys
<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb;data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
... <configProtectedData> <providers> <add keyContainerName="CustomKeys" useMachineContainer="true" description="Uses RsaCryptoServiceProvider to encrypt and decrypt" name="CustomProvider" type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </providers> </configProtectedData> ...
aspnet_regiis -pe "connectionStrings" -app "/WebFarmRSA" -prov "CustomProvider"
If the encryption is successful, you will see the following output:
Encrypting configuration section... Succeeded!
Your modified Web.Config file, with the connectionStrings section encrypted, should be similar to the following example:
... <connectionStrings configProtectionProvider="CustomProvider"> <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> <CipherValue>MWOaFwkByLRrvoGYeFUPMmN7e9uwC0D7gFEeyxs3Obll710dLQvD5XaMWcRxg1WwtOE9nysPQRrIJUaCm0b26LGUoa/giGEfvWnslU2kig9SPICzsQAqUSB/inhRckWceb2xdy7TT+EI/vfsu6itJwE2AicMCTwx5I828mP8lV4=</CipherValue> </CipherData> </EncryptedKey> </KeyInfo> <CipherData> <CipherValue>IKO9jezdlJ/k1snyw5+e11cd9IVTlVfHBHSiYLgICf1EnMNd5WxVDZWP1uOW2UaY3Muv7HrSZCRbqq6hfA2uh2rxy5qAzFP+iu7Sg/ku1Zvbwfq8p1UWHvPCukeyrBypiv0wpJ9Tuif7oP4Emgaoa+ewLnETSN411Gow28EKcLpbKWJDOC/9o7g503YM4cnIvkQOomkYlL+MzMb3Rc1FSLiM9ncKQLZi+JkRhlDIxFlsrFpKJhdNf5A0Sq2P71ZLI6G6QDCehHyn3kCZyBmVWJ0ueoGWXV4y</CipherValue> </CipherData> </EncryptedData> </connectionStrings> ...
aspnet_regiis -px "CustomKeys" "C:\CustomKeys.xml" -pri
The -pri switch causes the private and public key to be exported. This enables both encryption and decryption. Without the–pri switch, you would only be able to encrypt data with the exported key.
If the command is successful, you will see the following output:
Exporting RSA Keys to file... Succeeded!
aspnet_regiis -pi "CustomKeys" "C:\CustomKeys.xml"
If the command is successful, you will see the following output:
Importing RSA Keys from file.. Succeeded!
Note After you have finished exporting and importing the RSA keys, it is important for security reasons to delete the CustomsKeys.xml file from both machines.
The account used to run your Web application must be able to read the RSA key container. If you are not sure which identity your application uses, you can check this by adding the following code to a Web page:
using System.Security.Principal; ... protected void Page_Load(object sender, EventArgs e) { Response.Write(WindowsIdentity.GetCurrent().Name); }
By default, ASP.NET applications on Windows Server 2003 run using the NT Authority\Network Service account. The following command grants this account access to the CustomKeys store:
aspnet_regiis -pa "CustomKeys" "NT Authority\Network Service"
If the command runs successfully, you will see the following output.
Adding ACL for access to the RSA Key container... Succeeded!
You can check the ACL of the file in the following folder:
\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
Your RSA key container file will be the one in this folder with the most recent timestamp.
<%@ Page Language="C#" %> <script runat="server"> protected void Page_Load(object sender, EventArgs e) { Response.Write("Clear text connection string is: " + ConfigurationManager.ConnectionStrings ["MyLocalSQLServer"].ConnectionString); } </script> <html> <body/> </html>
MyLocalSQLServer is the name of the connection string you specified previously in the Web.config file.
Provide feedback by using either a Wiki or e-mail:
We are particularly interested in feedback regarding the following:
Technical support for the Microsoft products and technologies referenced in this guidance is provided by Microsoft Product Support Services (PSS). For product support information, please visit the Microsoft Product Support Web site at http://support.microsoft.com/.