How To: Encrypt Configuration Sections in ASP.NET 2.0 Using RSA
2009-03-10 17:09 Valens 阅读(1240) 评论(0) 编辑 收藏 举报由于出现了“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
Applies To
- ASP.NET version 2.0
- Microsoft® Windows Server™ 2003 operating system
Summary
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.
Contents
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
Objectives
- Learn about key changes for encrypting sensitive data in configuration files in ASP.NET version 2.0.
- Learn how to choose between machine-level and user-level containers.
- Know which sections can and cannot be encrypted with the RSA protected configuration provider.
- Use the RSA protected configuration provider to encrypt connection strings.
- Create RSA key containers.
- Import and export RSA keys across multiple servers in a Web farm.
Overview
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:
- <appSettings>. This section contains custom application settings.
- <connectionStrings>. This section contains connection strings.
- <identity>. This section can contain impersonation credentials.
- <sessionState>. This section contains the connection string for the out-of-process session state provider.
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.
What's New in 2.0
.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.
- RSAProtectedConfigurationProvider. This is the default provider and uses the RSA public key encryption to encrypt and decrypt data.
- DPAPIProtectedConfigurationProvider. This provider uses the Windows Data Protection API (DPAPI) to encrypt and decrypt data.
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.
Summary of Steps
To encrypt configuration sections by using the RSA protected configuration provider, perform the following steps:
- Step 1. Identify the configuration sections to be encrypted.
- Step 2. Choose machine-level or user-level key containers.
- Step 3. Encrypt your configuration file data.
Step 1. Identify the Configuration Sections to Be Encrypted
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.
Sections You Cannot Encrypt Using Protected Configuration
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:
- <processModel>
- <runtime>
- <mscorlib>
- <startup>
- <system.runtime.remoting>
- <configProtectedData>
- <satelliteassemblies>
- <cryptographySettings>
- <cryptoNameMapping>
- <cryptoClasses>
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.
Step 2. Choose Machine-Level or User-Level Key Containers
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.
Machine Key Container
Use a machine-level key container in the following situations:
- Your application runs on its own dedicated server with no other applications.
- You have multiple applications on the same server and you want those applications to be able to share sensitive information and the same encryption key.
RSA machine key containers are stored in the following folder:
\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
User Key Container
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
Step 3. Encrypt Your Configuration File Data
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.
Using RSA with a Machine-Level Key Container to Encrypt a Connection String in Web.Config
The RSAProtectedConfigurationProvider is the default provider and is configured to use the machine-level key container.
To encrypt the connectionStrings section in Web.config
- Create a new Web site named MachineRSA. Make sure that this directory is configured as a virtual directory.
- Add a Web.config configuration file to this directory.
- Add a sample connectionString similar to the following example:
<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb; data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
- Run the following command from a .NET command prompt to encrypt the connectionStrings section:
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>
- The -pe switch specifies the configuration section to encrypt. This is the XML element name of the configuration section.
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".
- The -pef switch specifies the configuration section to encrypt and allows you to supply the physical directory path for your configuration file.
- The -app switch specifies your Web application's virtual path. If it is a nested application, you need to specify the nested path from the root directory; for example, "/test/aspnet/MachineRSA".
- Because you are using the default provider with default settings, you do not need to use the–prov switch, which specifies the provider name.
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
- The -pe switch specifies the configuration section to encrypt. This is the XML element name of the configuration section.
- Review the Web.config file, and examine the changes. The following elements are created:
- <EncryptedData>
- <EncryptionMethod>
- <KeyInfo>
- <EncryptedKey>
- <KeyName>
- <CipherData>
- <CipherValue>
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> ...
- Add the following Default.aspx Web page to your application's virtual directory, and then browse to this page to verify that encryption and decryption work correctly.
<%@ 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
- If you are not sure which identity to use, check the identity from a Web page by using the following code:
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. Open a .NET command prompt, and use the following command to give this account access to the NetFrameworkConfigurationKey store:
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.
- If you are not sure which identity to use, check the identity from a Web page by using the following code:
- To change the connectionStrings section back to clear text, run the following command from the command prompt:
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
Using RSA with a User-level Key Container to Encrypt a Connection String in Web.config
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
- Create a new Web site named UserRSA. Make sure that this directory is configured as a virtual directory.
- Add a Web.config configuration file to this directory.
- Add a sample connectionString similar to the following example:
<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb;data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
- Add and configure a protected configuration provider to use a user-level key container. To do this, add the following <configProtectedData> section to your Web.config file. You must set useMachineContainer= "false" to instruct the provider to use the user-level key container. You must also use a unique provider name or a run-time error will be generated.
<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>
- Run the following command from an SDK Command Prompt to encrypt the connectionStrings section:
aspnet_regiis -pe "connectionStrings" -app "/UserRSA" -prov "MyUserRSAProtectedConfigurationProvider"
- The -pe switch specifies the configuration section to encrypt. This is the XML element name of the configuration section.
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".
- The -app switch specifies your Web application's virtual path. If it is a nested application, you need to specify the nested path from the root directory; for example, "/test/aspnet/MachineRSA".
- The -prov switch specifies the provider name. In this case, this is set to "MyUserRSAProtectedConfigurationProvider" which is the name you specified when configuring the provider in step 4.
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
- The -pe switch specifies the configuration section to encrypt. This is the XML element name of the configuration section.
- Review the Web.config and examine the changes. The following elements are created.
- <EncryptedData>
- <EncryptionMethod>
- <KeyInfo>
- <EncryptedKey>
- <KeyName>
- <CipherData>
- <CipherValue>
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> ...
- Add the following Default.aspx Web page to your application's virtual directory, and then browse to this page to verify that encryption and decryption works correctly.
<%@ 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
- To change the connectionStrings section back to clear text, run the following command from the .NET command prompt:
aspnet_regiis -pd "connectionStrings" -app "/UserRSA"
If the command is successful, you will see the following output:
Decrypting configuration section... Succeeded!
Web Farm Scenarios
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.
Using the RSA Provider to Encrypt a Connection String in Web.config in a Web Farm
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
- Run the following command from a command prompt to create a custom RSA encryption key:
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 - Create a new Web project named WebFarmRSA. Make sure that this directory is configured as a virtual directory.
- Add a Web.config configuration file to this directory.
- Add a sample connectionString similar to the following example:
<connectionStrings> <add name="MyLocalSQLServer" connectionString="Initial Catalog=aspnetdb;data source=localhost;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> </connectionStrings>
- Add and configure a custom protected configuration provider. To do this, add the following <configProtectedData> section to the Web.config file. Note that the key container name is set to "CustomKeys", which is the name of the key container created previously.
... <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> ...
- Run the following command from an SDK Command Prompt to encrypt the connectionStrings section using the custom RSA key:
aspnet_regiis -pe "connectionStrings" -app "/WebFarmRSA" -prov "CustomProvider"
If the encryption is successful, you will see the following output:
Encrypting configuration section... Succeeded!
- Review the Web.config file and examine the changes. The following elements are modified:
- <EncryptedData>
- <CipherData>
- <CipherValue>
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> ...
- Run the following command from a .NET command prompt to export the custom RSA encryption key:
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!
- Deploy the application and the encrypted Web.config file on a different server computer. Also copy the CustomKeys.xml file to a local directory on the other server, for example to the C:\ directory.
- On the destination server, run the following command from a command prompt to import the custom RSA encryption keys:
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.
- Grant access to the ASP.NET application identity.
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.
- Add the following Default.aspx Web page to your application's virtual directory, and then browse to this page to verify that encryption and decryption work correctly.
<%@ 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.
Additional Resources
Feedback
Provide feedback by using either a Wiki or e-mail:
- Wiki. Security Guidance Feedback Wiki page: http://channel9.msdn.com/wiki/default.aspx/Channel9.SecurityGuidanceFeedback
- E-mail. Send e-mail to mailto:%20secguide@microsoft.com.
We are particularly interested in feedback regarding the following:
- Technical issues specific to recommendations
- Usefulness and usability issues
Technical Support
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/.