C#基础之.NET环境下WebConfig的加密

在将ASP.NET项目部署到服务器上时,内网环境下Web.Config每每是直接复制过去。对于外网环境,则须要对Web.Config文件进行加密。web

.NET环境下一共提供了2种方式的加密功能,分别是DpapiProtectedConfigurationProvider和RsaProtectedConfigurationProvider提供程序。sql

前者在本机加密Web.Config后,只能在本机进行解密,若是须要将Config文件复制到外部主机,则没法进行解密。后者在本机加密Config文件后,能够处处密钥容器,当把Config文件复制到外部主机后,可对先前导出的文件进行导入功能,导入后既可自动解密。c#

因为常常须要复制Config文件到外部主机,所以Rsa保护程序更加适用于实际业务场景,本文将详细介绍RsaProtectedConfigurationProvider程序的使用步骤。api

1. 使用RsaProvider提供程序,须要首先进入.NET Framework运行环境,能够配置环境变量或使用cd指令。服务器

cd  C:\Windows\Microsoft.NET\Framework\v2.0.50727session

2. 接着即可以使用aspnet_regiis.exe建立一个Rsa密钥容器。密钥容器分用户级别和计算机级别两种状况,因为使用用户级别密钥没什么益处,通常使用计算机级别既可。asp.net

aspnet_regiis -pc "MyKeys" -expide

3. 建立密钥容器后,还须要设置密钥容器的访问权限,下面的命令授予NETWORK SERVICE 账户对计算机级别的 “MyKeys” RSA 密钥容器的访问权限。msdn上有一个aspx程序会展现你的asp.net程序的用户标志,不过本人实际执行pa指令后会报错。网站

aspnet_regiis -pa "MyKeys" "NT AUTHORITY\NETWORK SERVICE"加密

4. 在Web.Config文件中加上以下配置节点,MyProvider为你的保护程序名称,可随意指定。keyContainerName为前面设置的密钥容器名称,useMachineContainer为true表示使用计算机级别密钥,为false表示使用使用用户级密钥。

这段配置节不要像msdn那样直接放在configure配置节点下面,这样会报错,建议放在你须要加密节点的后面。

   <configProtectedData>
      <providers>
         <add name="MyProvider"
              type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,
                    Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,
                    processorArchitecture=MSIL"
              keyContainerName="MyKeys" 
              useMachineContainer="true" />
      </providers>
   </configProtectedData>

 5 .下面的指令将对指定路径下的config文件节点进行加密,若是配置文件中还有session的sql链接字符串,也能够对sessionState节点进行加密。

aspnet_regiis -pef "connectionStrings"  "D:\WebApp"  -prov   "MyProvider"

aspnet_regiis -pef "system.web/sessionState"  "D:\WebApp"  -prov   "MyProvider"

  加密后的connectionStrings节点以下所示,此时仍可访问ASP.NET应用程序。

  <connectionStrings configProtectionProvider="MyProvider">
    <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>X3XoBfbo/h9QUeVUV8A1EGMM0NQuBnhfuC/iV1e7CCmGaiRt9ogmICenTK8VAmGfhufPzWFu5UUHSiO/6BIvYPEO5WoWlj3h5/sUQmRj6NsAJOnrnYHEjta4oQb4XajxazWcf3HUeWR0mG4wDCiUfTZaRIRmXkGgfbxewpsKJ5k=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>suqFgGjGFaon62YNI2VM5SQymcf4yyAku9fWQuvgClj1bfqixK9kIs9IE0I0m2u4gLbF+y0xPharfcOFJpXHDwHoaCrNQsxsutqiXquX67bYcJeYaMz5ja9ebqAtQvKIiZ/kHGvFIPXSCg5HiW/GGQwaf3FESVEsOaSAJZ3JJk9MlkkwDd6LepgtcCVjLnEK0lOeEFznrngizFFZWAsYjh5UCF5lNxNxf/IBwtznsfiFi2tV1F4sx9HkJEEryf5MEtu1RAA/wqarMvn7dlXhpGconpNPXA1IGlTmaZ/S1bR/FsO39skgHrs+OHsDMbJrI5ZO4TXXbK/DD86GPzu9JXrVKNVImzzW0V8aMc2HcVNClPsMwwgGaH6PNhE0xkjV6YH77XcLdVsKibvnwMlO/4kjGKoNXaSkFBoAEgprzi8=</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>

 若是须要解密,能够执行下面这条指令aspnet_regiis -pdf "connectionStrings" "D:\WebApp"

<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WebApp-20170622060005.mdf;Initial Catalog=aspnet-WebApp-20170622060005;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

6. 导出密钥容器,密钥信息将被存储在导出的xml文件中,pri表示将公钥和私钥一块儿导出。

aspnet_regiis  -px "MyKeys" "D:/MyKeys.xml"  -pri

7.  有了这个xml文件,就至关于有了密钥容器,导出密钥容器后能够对密钥容器进行删除,删除指令以下。

aspnet_regiis  -pz  "MyKeys" 

8. 删除密钥容器后,若是前面你没有对Config文件进行解密,那么运行ASP.NET程序将会直接报错。

    在本人实际操做中发现,若是对正在运行的ASP.NET应用程序的Web.Config文件进行加密,加密后当即删除密钥,此时点击运行(不调试)仍可正常访问。这代表Rsa解密操做在内存中执行,只有从新生成解决方案或调试(会执行生成操做)后,访问才会报错。

9. 如今能够将加密后的config文件和导出的MyKeys.xml一块儿复制到服务器上,此时运行网站将会直接报错,需执行下面的导入指令。

aspnet_regiis -pi "MyKeys"  "D:/MyKeys.xml"

导入后,在本机访问ASP.NET网站会发现仍然报错,提示没法open  Provider。这个坑最终在网上找到解决方法,以下面指令所示,须要为应用程序池设置对密钥容器的访问权限。

aspnet_regiis -pa "MyKeys"   "IIS APPPOOL\MyWeb" -full

自此整个流程已结束,能够将上面这些指令封装成2个批处理程序,一个是密钥制做bat,一个是导入bat,以下所示。

@echo on
cd C:\Windows\Microsoft.NET\Framework\v2.0.50727

::设置config地址,config文件要在E:\test下面
set configAddress="E:\test"

::建立RSA密钥容器
aspnet_regiis -pc  "MyKeys" -exp

::设置密钥容器访问权限
aspnet_regiis -pa "MyKeys" "NT AUTHORITY\NETWORK SERVICE"

::加密
aspnet_regiis -pef "connectionStrings"  "D:\WebApp"  -prov   "MyProvider"

aspnet_regiis -pef "system.web/sessionState"  "D:\WebApp"  -prov   "MyProvider"

::导出
aspnet_regiis  -px "MyKeys" "D:/MyKeys.xml"  -pri

::删除密钥容器
aspnet_regiis  -pz  "MyKeys" 

pause
@echo on
cd C:\Windows\Microsoft.NET\Framework\v2.0.50727

::删除旧的密钥容器
aspnet_regiis  -pz  "MyKeys" 

::导入新的密钥容器
aspnet_regiis -pi "MyKeys"  "D:/MyKeys.xml"

::设置应用程序池的访问权限
aspnet_regiis -pa "MyKeys"   "IIS APPPOOL\MyWeb" -full

pause

在写完这2个bat后,我想起前面的解密指令aspnet_regiis -pdf "connectionStrings" "D:\WebApp",它只须要提供节点名称和路径。也就是说,若是攻击者可以在被攻击的服务器上执行cmd指令,那么他就能够对config进行解密。这个问题若有前辈有更好的解决方式,欢迎您指导留言

若是当初微软编写这个指令解析方法时,加上一个key的参数。那么即便攻击者可以执行cmd指令,因为不知道key的名称,因此仍然没法对config进行解密。

声明:本文原创发表于博客园,做者为方小白 ,若有错误欢迎指出。本文未经做者许可不准转载,不然视为侵权。

相关文章
相关标签/搜索