[.NET]如何對config檔案的連線字串自訂加密

  • 2211
  • 0
  • 2019-09-12

[.NET]如何對config檔案的連線字串自訂加密

這邊用的是AES加密演算法做家密
字串加密的程式碼細節就不在這邊贅述,可先看本部落格的文章參考參考

首先先在config檔案裡面的appsettings加入已經加密好的連線字串:
(從web.confif裡面的連線字串複製過來,並且把password的部分利用AES演算法做加密)

<add key="UseEncryptConnectionString" value="true"/>
<add key="EncryptConnectString_Db1Entity" value="metadata=res://*/MyDataModel.csdl|res://*/MyDataModel.ssdl|res://*/MyDataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=BCRI_Face;persist security info=True;user id=myAccount;password=CVXEB8xfAs0w5t9R2B5XeQ==;MultipleActiveResultSets=True;App=EntityFramework&quot;"/>
<add key="EncryptConnectString_Db1" value="Data Source=localhost;initial Catalog=BCRI_Face;Persist Security Info=False;Uid=myAccount;Password=CVXEB8xfAs0w5t9R2B5XeQ==;"/>


然後在整個專案共用的class裡面,加入快速存取解密後的連線字串的function:

//取得加密的連線字串
public static string GetEncryptedConnStr(EncryptedConnStr connStr)
{
	string result = "";

	
	if(System.Configuration.ConfigurationManager.AppSettings["UseEncryptConnectionString"].ToLower()
		== "true")
	{
		//result = CryptDecryptString(
		//            System.Configuration.ConfigurationManager.AppSettings[connStr.ToString()]);
		string encryptedConnStr = System.Configuration.ConfigurationManager.AppSettings[connStr.ToString()];
		string encryptedPwd = "";
		string pwd = "";
		string regPattern = @"";
		Match m;
		if (encryptedConnStr.ToLower().Contains("metadata") == true)
		{
			//包含metadata表示是EF用的connection string 
			regPattern = "password=(?<value>.*?);Mult";
			
		}
		else
		{
			//不包含metadata表示是 ado.net用的connection string,專門用來執行 raw sql
			regPattern = "Password=(?<value>.*?);";                   
		}
		m = Regex.Match(encryptedConnStr, regPattern, RegexOptions.Singleline);
		encryptedPwd = m.Groups["value"].Value;
		pwd = CryptDecryptString(encryptedPwd);
		result = encryptedConnStr.Replace(encryptedPwd, pwd);
		result = result.Replace("&quot", "\"");
	}
	else
	{
		//do nothing
	}   

	return result;
}

//取得加密的連線字串
public enum EncryptedConnStr
{
	EncryptConnectString_Db1Entity,//用EF連接db1
	EncryptConnectString_Db2Entity,//用EF連接db2
	

}


接著要用partial class去overwrite由EF自動產生的DbContext,首先先看一下原本自動產生的長什麼樣子:


接下來請於專案內新增一個partial class,來overwrite這個DbContext,內容如下:
這樣子就可以在使用EF的時候,傳入連線字串

//name space必須跟EF自動產生的一樣
namespace MyWebProject.Models
{
    //讓這個entity連線的時候可以輸入連線字串
    public partial class MyWebEntities
    {      
        public MyWebEntities(string cnStr) : base(
            string.IsNullOrEmpty(cnStr) ? "name=MyWebEntities" : cnStr)
        {

        }

       
    }
}


EF實際上使用方式如下:

 using (MyWebEntities ctx = new MyWebEntities(
               GetEncryptedConnStr(EncryptedConnStr.EncryptConnectString_Db1Entity)
               ))
{
	
}

//這是原本使用EF的使用方式
// using (MyWebEntities db = new MyWebEntities()
// {
	
// }


大概是這樣………


參考資料:
EF_connection string加密後,使用解密發生Error,'不支援關鍵字 data source'  - 阿倫的學習天地
https://dotblogs.com.tw/alanlun/2017/02/07/110445
Entity Framework 連線字串加密 - YuShu Hsiao
https://dotblogs.com.tw/h20/2017/12/25/142557
為EF連線字串加密的簡單範例 - 黑暗執行序
https://blog.darkthread.net/blog/encrypt-ef-connstring/