1. 程式人生 > >C# Web.Config 加密與解密

C# Web.Config 加密與解密

用後臺編碼的形式對web.config資料庫連線字串或者某個節點進行加密
這裡提供倆種方式:
DataProtectionConfigurationProviderRSAProtectedConfigurationProvider

編碼形式
新建一個空網站新增Web窗體頁面WebConfigRSA.aspx
範例:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form
id="form1" runat="server">
<div> <h2>使用“DataProtectionConfigurationProvider”</h2> <h2>對web.config 中 &lt;connectionStrings&gt;&lt;/connectionStrings&gt;節點加密</h2> <asp:Button ID="btnJiaM" runat="server" Text="Data加密" onclick
="btnJiaM_Click" />
<br /> <br /> <asp:Button ID="btnJieM" runat="server" Text="Data解密" onclick="btnJieM_Click" /> </div> <div> <h2>使用“RSAProtectedConfigurationProvider”形式來加密</h2> <h2>對web.config 中 &lt;connectionStrings&gt;&lt;/connectionStrings&gt;節點加密</h2
>
<asp:Button ID="btnRsaJiaM" runat="server" Text="RSA加密" OnClick="btnRsaJiaM_Click" /> <br /> <br /> <asp:Button ID="btnRsaJieM" runat="server" Text="RSA解密" OnClick="btnJieM_Click" /> </div> </form> </body> </html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Web.Configuration;

namespace WebCfProtection
{
    public partial class WebConfigRSA : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// DataProtectionConfigurationProvider加密webconfig
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnJiaM_Click(object sender, EventArgs e)
        {
            Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
            ConfigurationSection section = config.GetSection("connectionStrings");

            if (section != null && !section.SectionInformation.IsProtected)
            {
                section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
                config.Save();
            } 
        }

        /// <summary>
        /// DataProtectionConfigurationProvider
        /// RSAProtectedConfigurationProvider    
        /// 倆種解密方式一樣
        /// 注意;加密和解密必須在同一臺機子上(例如在伺服器上加密的web.config 將密文拿到另一臺機子上去解密是沒辦法成功的)
        /// 解密webconfig
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnJieM_Click(object sender, EventArgs e)
        {
            Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
            ConfigurationSection section = config.GetSection("connectionStrings");

            if (section != null && section.SectionInformation.IsProtected)
            {
                section.SectionInformation.UnprotectSection();
                config.Save();
            } 
        }

        /// <summary>
        /// RSAProtectedConfigurationProvider 加密web.config
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnRsaJiaM_Click(object sender, EventArgs e)
        {
            Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);
            ConfigurationSection section = config.GetSection("connectionStrings");

            if (section != null && !section.SectionInformation.IsProtected)
            {
                section.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");
                config.Save();
            }
        }



    }
}

web.config

<?xml version="1.0" encoding="utf-8"?>

<!--
  有關如何配置 ASP.NET 應用程式的詳細訊息,請訪問
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

  <connectionStrings>
    <add name="ConnectionString" connectionString="User Id=cxp;Password=cxp123;Data Source=WZ_CXP; pooling=true;min pool size = 2;max pool size = 20;connection lifetime = 20;Persist Security Info=True;"
      providerName="Oracle.DataAccess.Client" />
  </connectionStrings>

</configuration>

DataProtectionConfigurationProvider加密webconfig後的檔案對比

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

  <connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
    <EncryptedData>
      <CipherData>
        <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAApBayeiiRRkCPnHwQ/Gc6NgQAAAACAAAAAAAQZgAAAAEAACAAAADQaRTrjrRm+WEzQlALGVyWr7UkJJcDtfEanxUMuzeSSwAAAAAOgAAAAAIAACAAAADViuHu1S+IdiAAW4jh9/yJl5m8cL3M1xGAV6BW5cLQUlACAADJl+g82iyx7+lv3bbbxCMaXAf4YgbyRE9HjiABcWrIi6bAWRljptR+djZ9wOKOXTwo6qGeW7zXRcu29TIR6vQGfcTnNeeCCNSFDe8haBBrbE97+xfRWCqwW+rYCHkOzDdgXt4KLEEVJD9cB8fRpg/LhLxRAquuk2CqPYDatuww7s+qfPjkOi7dKqPtq8WHgYDiP5HQElE6Rn6vUX60GPnXKY5ZySQKFsw4DdLJW9be0YWxbBR+5RpbBC09/9Ww0fOdjnaqiDpkhOG8gTsCNJ/7t/Zo6w0IscKkFogIzBGNF8JvX8EpqxcBpqHJ2TjrvNWsj/bLM5b7OEON2KZUyekE03m09yhKrDJKnpoD6k0ZgWTKWVS1xRJpAbhCsqgjnIUbVX0FJh8NudQ41Ux6Niq0mU4uX8MjZPNrZp6DVp7JOHuVvdxssJMXuCR7eUg7IHYFhtuDhOct45h5EJxuBdrgyMXUVv+4zHa+LyQOxWqhaGVAsDNn/oA61qElZRZXwL+tOUZAnnuNd5QHGiduGxzCWVoATfal2Eu5bMwxi8mwpTSHJPFwhNPK1X1c/vgCxyfdwKobzQl8MGrzAKtCA0hb2DGL95IOvUxKVBbuTNv/Rwbpjnjc72uGiwaW5MF1PxXZU7/OcC0mKZUdHqzMl4/QFAZE4d9He98oLSM61okO7+cZSahGqtpClxlkKaQZTbJ8b2s32JbLGDyfcwmR7r5DOO5tZKr+zoKC6PiQsNkWg10uRBp1eLvM3j49rNt3+krK/xjHBglRB1WyPU4bqFj0QAAAAK7BcyM5eK+5H21IxTNOxspi0b/1oKMLTlwKFjHvowIeNNPRFL9LHtCxmSvs/tRFDQP3cAh0lEmBJ4XZjB60WuY=</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>

</configuration>

RSAProtectedConfigurationProvider 加密web.config後的檔案對比

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

  <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>wS8zmwLfvJWvu0pWuWdpumwi+pXEBw3j5IQ4ny6JQCkXqeqBX7F89oHxWF2MpThbqb4txIygt9LSmwmDC/ooGW4j+vYjkVV8NxJNOy9D9TJp+G3egSMBiWkZfU95QpPTd/O1cmof2kYtUoIZcUqvk21FJi0/1xLO1ViBhBf4AiQ=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>o+t1yi+NdVU22Mi2ftZ4DXyIdvnrj431T3Ud9UbGPGsLBl2YFTlj1vaj7LhFLSwXdvVpn3ffd1FUfRyevseRAz1M79+walyisRv+7xX+X/OkfbtH4fKhE4cyUR+FeKRArD/bLnRz4G3aBUvBaiWaVtaDrEPD1s4dMdvDBDMd7BSP86fNsoGCUFBMMRBEbTKP3UO5YagvuT5RBE8Hh6I2RrbfT6ZFWXsmCMfoOFcSYiDUbLzWuX02nBzDZJVTMiHoTZqxAbfr4fpXONkO3Fq7Ihj1yZfKlu+cbRtHxrAfp6Ro4tNRrwwo/0xgT4bUaD5q5v8GmbTYcAY/tXxL+ImLwL7vd+syRDxamErrqL+0eP17b4MGj3l82e8ubFPbwKvWR4m/efFuW3IAMQkK185uNw==</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>

</configuration>

非編碼形式-利用Visual Studio 命令提示(2010)
開始–>程式–>Microsoft Visual Studio 2010–>Visual Studio Tools–>Visual Studio 命令提示(2010)

加密
aspnet_regiis -pef "connectionStrings" "D:\wzfb"

解密
aspnet_regiis -pdf "connectionStrings" "D:\wzfb"

同樣是用上面的案例的web.config 加密後得到的格式如下:

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

  <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>G6d6t1Sxntr8OouOy7CLDVI+sRrvbCUc/04Pn9OruiHrchpg5Q0sxoo96rLLXbg027tOeVhxWWCaSgED6PxoYyvsyrrI2EXbgUd9pxTKxgToKtAXrjjBeJBw4qfxD73S4DHVzM85mifVlG/upT3ASaSzvyOPxH1jdlTklTxCoig=</CipherValue>
          </CipherData>
        </EncryptedKey>
      </KeyInfo>
      <CipherData>
        <CipherValue>5C5imqKACI22LLyLlLyP437QvNnC8A82PgbbdBNGrYWmbNe9hTtplP6iLfhwZvQmjzO+E/laUuYIWcaIhupbqC8GuSjvUekweqHRJRr95iEFXeey8pkm4CzWKJU0cui5+HzUL7nkvZ5+EHX1a1kdgZiGSjVcOwT0XDUiFc1i59vMXWeMkQhGBJ9TkdiwidQMJRiuWh7PQ1JIALv14Fo+L/r2Ikv2CPSU+lJT4npNnHpvkwmfljvKPnDPuKVxgoCk5EftAhbPpvj/60eexN3wWr3Ml9xkP7p0/dACj/LMv9UpoOpGerGuWFVolo0C8io5+Jt6ycUzQ1iQGC1aNNZkTQ6N1E823Hv/v3xOCSYhUbQ05qlKxY8WZjgLv3mIgdZs78LGXUaeYuPCj5xE0GkFbg==</CipherValue>
      </CipherData>
    </EncryptedData>
  </connectionStrings>

</configuration>

基本上得出的結論是非編碼形式-利用Visual Studio 命令提示(2010) 得到結果和 編碼形式RSAProtectedConfigurationProvider 得到結果一致。(Visual Studio 命令提示(2010)加密 = RSAProtectedConfigurationProvider加密)

錯誤及解決方案
1.釋出時許可權不夠是由於network service帳戶無法訪問 賦予network service讀許可權(操作方便給everyone使用者全賦)
2.命令列加密、解密失敗格式不一致或者空格。
例如:
參考文獻中有些文章有些案例是這種寫法aspnet_regiis**.exe** 導致加密解密失敗

aspnet_regiis.exe -pef "connectionStrings" "D:\wzfb"

後續補充
2017-05-02 補充
頁面增加測試按鈕用於測試加密前與加密後,是否需要改變獲取web.config中connectionStrings節點的方式。

 <div>
        <h2> &lt;connectionStrings&gt;&lt;/connectionStrings&gt;節點加密與未加密獲取資料是否成功</h2>
        <asp:Label ID="lblDate" runat="server" Text="點選獲取資料按鈕"></asp:Label>
        <br />
        <asp:Button ID="btnHqsj" runat="server" Text="獲取資料" OnClick="btnGetData_Click" />
    </div>

DbHelperOra中的獲取ConnectionString節點的方式

public static string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

測試結果是不管是加密前還是加密後都不需要修改DbHelperOra中的獲取ConnectionString節點的方式。
都是可以成功連線到資料庫從而獲取資料。(之所以寫這篇文章是我碰到過在老專案中增加了A功能,其中A功能正常執行過一段時間後,再次更新A功能迭代版本而無法訪問資料庫,從而懷疑是wen.config加密引起的,但web.config從始自終都是加密的。怎麼會有更新後只有A功能模組無法訪問,而老功能都正常的這種特殊情況. 在測試環境都是正常的,無法復現 )
2017-05-02 更新原因找到了具體為 不支援關鍵字: “connection timeout”