ASP.NET 2.0加密解密Web.config配置文件

Posted on 2009-07-22 12:25  lwjun  阅读(1562)  评论(1编辑  收藏  举报
可以使用受保护配置来加密 Web 应用程序配置文件(如 Web.config 文件)中的敏感信息(包括用户名和密码、数据库连接字符串和加密密钥)。对配置信息进行加密后,即使攻击者获取了对配置文件的访问,也可以使攻击者难以获取对敏感信息的访问,从而改进应用程序的安全性。 针对asp.net 2.0的应用程序的数据库链接字符串进行加密:例如,未加密的配置文件中可能包含一个指定用于连接到数据库的连接字符串的节,如下面的示例所示: <configuration>  <connectionStrings>
    <add name="SampleSqlServer" connectionString="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind;" />
  </connectionStrings>
</configuration>
ASP.NET 2.0 中有一个新的安全特性.可以对 Web.config 文件中的任何配置节进行加密处理,可以通过手工运行工具aspnet_regiis或者编程来完成这个工作。如果你可以直接访问你的Web 服务器,你可以通过运行如下的命令行:  cd  %windows%\Microsoft.NET\Framework\versionNumber aspnet_regiis -pe "connectionStrings" -app "/SampleApplication" –prov RsaProtectedConfigurationProvider -pd section
对配置节进行解密。此参数采用下面的可选参数: ·        -app virtualPath  指定应该在包含路径的级别进行解密。 ·        -location subPath  指定要解密的子目录。 ·        -pkm  指定应该对 Machine.config 而非 Web.config 文件进行解密。

-pdf section webApplicationDirectory
对指定物理(非虚拟)目录中的 Web.config 文件的指定配置节进行解密。

-pe section
对指定的配置节进行加密。此参数采用下面的可选修饰符: ·        -prov provider  指定要使用的加密提供程序。 ·        -app virtualPath    指定应该在包含路径的级别进行加密。 ·        -location subPath  指定要加密的子目录。 ·        -pkm  指定应该对 Machine.config 而非 Web.config 文件进行加密。

-pef section webApplicationDirectory
对指定物理(非虚拟)目录中的 Web.config 文件的指定配置节进行加密。
  如果你是使用虚拟主机等不能访问物理的服务器,你仍然能够通过编程方式加密的连接字符串: 1 Configuration config = Configuration.GetWebConfiguration(Request.ApplicationPath);
2 ConfigurationSection section = config.Sections["connectionStrings"];
3 section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");;
4 config.Update ();或者 config.Save();


//加密web.Config中的指定节
    private void ProtectSection(string sectionName)
    {
        Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
        ConfigurationSection section = config.GetSection(sectionName);
        if (section != null && !section.SectionInformation.IsProtected)
        {
            section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
            config.Save();
        }
    }

    //解密web.Config中的指定节
    private void UnProtectSection(string sectionName)
    {
        Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
        ConfigurationSection section = config.GetSection(sectionName);
        if (section != null && section.SectionInformation.IsProtected)
        {
            section.SectionInformation.UnprotectSection();
            config.Save();
        }
    }



现在, 使用受保护配置对连接字符串值进行加密的配置文件不以明文形式显示连接字符串,而是以加密形式存储它们,如下面的示例所示:
<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>
            <CipherValue>RXO/zmmy3sR0iOJoF4ooxkFxwelVYpT0riwP2mYpR3FU+r6BPfvsqb384pohivkyNY7Dm4lPgR2bE9F7k6TblLVJFvnQu7p7d/yjnhzgHwWKMqb0M0t0Y8DOwogkDDXFxs1UxIhtknc+2a7UGtGh6D
i3N572qxdfmGfQc7ZbwNE=
            </CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>KMNKBuV9nOid8pUvdNLY5I8R7BaEGncjkwYgshW8ClKjrXSM7zeIRmAy/cTaniu8Rfk92KVkEK83+UlQd+GQ6pycO3eM8DTM5kCyLcEiJa5XUAQv4KITBNBN6fBXsWrGuEyUDWZYm6Eijl8DqRDb
11i+StkBLlHPyyhbnCAsXdz5CaqVuG0obEy2xmnGQ6G3Mzr74j4ifxnyvRq7levA2sBR4lhE5M80Cd5yKEJktcPWZYM99TmyO3KYjtmRW/Ws/XO3z9z1b1KohE5Ok/YX1YV0+Uk4/yuZo0Bjk+rErG505YMfRVtxSJ4ee418
ZMfp4vOaqzKrSkHPie3zIR7SuVUeYPFZbcV65BKCUlT4EtPLgi8CHu8bMBQkdWxOnQEIBeY+TerAee/SiBCrA8M/n9bpLlRJkUb+URiGLoaj+XHym//fmCclAcveKlba6vKrcbqhEjsnY2F522yaTHcc1+wXUWqif7rSIPhc0+
MT1hB1SZjd8dmPgtZUyzcL51DoChy+hZ4vLzE=
        </CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>



////////////////////////
如果是自己的主机可以这么做,如果不是,每次加密都要把密钥告诉对方,工作量大,也不方便
通常而言,使用aspnet_regiis加密的web.config,但拷到另一台机器上后无法访问,这是因为密钥容器未被一起移植。
1.创建一个RSA密钥容器
aspnet_regiis -pc "MyKeys" -exp

2.授予asp.net标识对RSA容器的访问权限
      aspnet_regiis -pa "MyKeys" "NT AUTHORITY\NETWORK SERVICE"

3.在Web.config 中指定加密保护提供程序(Provider)
<configuration>
  <configProtectedData>
    <add name="MyProvider"
  type="System.Cofiguration.RsaProtectedConfigurationProvider"
  keyContainerName="MyKeys"
  useMachineContainer="true" />
  </configProtectedData>
</configuration>

4. 加密<connectionStrings>节
aspnet_regiis -pe "connectionStrings" -app "/MyApp" -prov "MyProvider"


5. 导出RSA 密钥容器
aspnet_regiis -px "MyKeys"  "c:\keys.xml" -pri


6. 删除RSA密钥容器
aspnet_regiis -pz "MyKeys"

7.从XML中导入RSA 密钥容器
aspnet_regiis -pi "MyKeys" "c:\keys.xml"

8.授予asp.net标识对RSA容器的访问权限
      aspnet_regiis -pa "MyKeys" "NT AUTHORITY\NETWORK SERVICE"




.net 2.0下加密和解密web.config文件中的某个section

aspnet_regiis –pef appSettings C:\Inetpub\wwwroot\website

aspnet_regiis –pdf appSettings C:\Inetpub\wwwroot\website


不过本人以为对web.config文件加密就应该每台机器的单独加密,因为导出导入密钥容器的工作更大,还不如单独加密效率高,安全性也要高一些。


.利用aspnet_regiis.exe工具加解密 

步骤:
1.先在本地生成RSA容器(有关RSA的详细操作,可参见http://msdn.microsoft.com/zh-cn/library/yxw286t2(VS.80).aspx )
aspnet_regiis.exe -pc "JimmyKeys" -exp
注:JimmyKeys为容器名字,可随便改


2.再将RSA导出到xml文件
aspnet_regiis.exe -px "JimmyKeys" "c:\JimmyKeys.xml"


3.在web.config中增加一节,一般放在<appSettings>之前就可以了,如下
<configProtectedData>
        <providers>
            <add name="JimmyRSAProvider"
                type="System.Configuration.RsaProtectedConfigurationProvider,System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                keyContainerName="JimmyKeys"
                useMachineContainer="true" />
           
        </providers>
    </configProtectedData>

        <appSettings>
        ...
       
4.将web.config加密
aspnet_regiis.exe -pef "appSettings" "c:\website" -prov "JimmyRSAProvider"

解密:
aspnet_regiis.exe -pdf "appSettings" "c:\website"


5.部署到远程服务器(1台或多台)
a.将网站文件与JimmyKeys.xml(也就是导出的RSA容器文件)先上传到服务器,同时导入RSA
aspnet_regiis.exe -pi "JimmyKeys" "c:\JimmyKeys.xml"


b.确认服务器上aspx登录所用的默认帐号
Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
随便建一个aspx,把上一行代码贴到里面就可以了,IIS5环境下输出的是ASPNET,IIS6环境下输出的是NETWORK SERVICE,IIS7下没试过也不知道输出的是啥玩意儿


c.授于RSA窗口的读取权限给b中的默认帐号
aspnet_regiis.exe -pa "JimmyKeys" "NETWORK SERVICE"


顺便把刚才这些个操作的命令整理成几个批处理
1.本机bat(新建RSA容器,导出容器,加密web.config)
%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pz "JimmyKeys"
%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pc "JimmyKeys" -exp
%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -px "JimmyKeys" "c:\JimmyKeys.xml"
%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pef "appSettings" "c:\website" -prov "JimmyRSAProvider"


2.远程服务器bat(导入RSA容器,授权)
%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pi "JimmyKeys" "c:\JimmyKeys.xml"
%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pa "JimmyKeys" "NETWORK SERVICE"



加密前:
<connectionStrings>
  <add name="connStr" connectionString="Data Source=server;Initial Catalog=Lib;User ID=sa;password=***"
  providerName="System.Data.SqlClient" />
</connectionStrings>
加密后:
<connectionStrings configProtectionProvider="JimmyRSAProvider">
  <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>breSi2wD4X4CAKh0puzhYtyltmR3cp9JfEE8Yw03NeWGZCOoEvDuxAceKLEsmYx8r/tI5NsZxOmY20pQzD1KvGELzz4rhkEPE9LKTAwyKNhqzMPFoRnjsdGTvs6JhrvVat9rdvgKbfTvVLXuvpXgSeNB0T6XJWq
/vOIU7KTyFjk=</CipherValue>
    </CipherData>
    </EncryptedKey>
  </KeyInfo>
  <CipherData>
   
<CipherValue>c4HD+EfJl//pv4eEzT938aWYhLyPBUt8lbNWf4Y4c6tewWLNBTwgYXtxPh6TnF8ne6s9H5C/AwXy/3JECuNEd8YGOO+RDhxw8NySd8vUc53+iUiHW5TLs/aoIvy8k1yOfLWGKFFWPtoX4F4gMTS+MAmhkiHQ46p
H2VyjyprNsl8LE2pGNjDOJnDeGYq+wkn2iw968+qjuTCibGJn6h6iGYGHYmkYUrgRzfo3iIZu+eCWE2IqCP+s58eQRjU3MxJ2BqeUU9HaKy4=</CipherValue>
  </CipherData>
  </EncryptedData>
</connectionStrings>
同样,这种方式加密后,aspx读取节点时也无需任何解密处理,代码不用做任何修改

注意:并不是所有的节点都能加密,ASP.NET 2.0仅支持对Web.config的部分配置节进行加密,以下配置节中的数据是不能进行加密的:
&#8226; <processModel>
&#8226; <runtime>
&#8226; <mscorlib>
&#8226; <startup>
&#8226; <system.runtime.remoting>
&#8226; <configProtectedData>
&#8226; <satelliteassemblies>
&#8226; <cryptographySettings>
&#8226; <cryptoNameMapping>
&#8226; <cryptoClasses>

另外,除了AppSettings和ConnectionStrings以外的其它节点,可以这样写:
aspnet_regiis.exe -pef "system.serviceModel/behaviors" "d:\website\cntvs\"

即对<system.serviceModel>下的<behaviors>节点加密,这一节点同样适用于代码方式加密,经过多次尝试,似乎除了AppSettings和ConnectionStrings以外的其它节点,只能支持二级节点。

象以下写法:
aspnet_regiis.exe -pef "system.serviceModel/behaviors/endpointBehaviors" "d:\website\cntvs" 
运行时会报错:
未找到配置节“system.serviceModel/behaviors/endpointBehaviors”。

转自:http://www.waydu.com/blog/4685

Copyright © 2024 lwjun
Powered by .NET 9.0 on Kubernetes